[Leetcode] 29. Divide Two Integers 解题报告

本文介绍了一种不使用乘法、除法和取模运算符实现整数除法的方法。提出了两种算法,一种时间复杂度为O(n),另一种更优的时间复杂度为O(log n)。后者利用了除数的指数增长特性来快速逼近结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

Divide two integers without using multiplication, division and mod operator.

If it is overflow, return MAX_INT.

思路

        我们在这里总结一下两种可能的思路(只考虑被除数和除数均为正数的情况):

1、只要被除数大于等于除数,就从被除数中减去除数,每减去一次结果就增加1。假设最终结果为n,则该算法的时间复杂度为O(n)。

2、只要被除数大于等于除数的2倍,我们就将除数和结果均乘以2,直到被除数小于除数的2倍。接着将被除数更新为被除数与除数的差,将除数恢复为最初的除数,并重复上述操作直到被除数小于除数。此时算法的时间复杂度降为O(logn)。

       O(logn)的复杂度要比O(n)好不少的。而这刚好涉及到几何级数和代数级数的概念。因为思路1中被除数是以代数级数的速度下降的,所以其时间复杂度为O(n);而思路2中除数是以几何级数的速度增长的,所以迭代中被除数也就是以几何级数的速度下降的,因此其时间复杂度为O(logn)。

       注意上述分析中n并不表示被除数和除数的规模,而是代表结果的规模。这类问题我们一般称为output-sensitive的。

       好多问题都可以从O(n)优化为O(logn),而这也是面试中经常会碰到的问题。我记得中Leetcode中还有好几道题目涉及到这一思想,例如求平方根,求幂等。建议读者把这几道题目结合起来一起练习,加深印象。

代码

class Solution {
public:
    int divide(int dividend, int divisor) 
    {
        // the only special case that might cause overflow
        if(dividend == INT_MIN && divisor == -1) 
            return INT_MAX;
        if(dividend == 0) 
            return 0;  
        long ans = 0;
        long nums1 = labs(dividend);
        long nums2 = labs(divisor);  
        while(nums2 <= nums1)  
        {  
            int cnt = 1;  
            while((nums2 << cnt) <= nums1) 
                cnt++;  
            ans += (1 << (cnt-1));
            nums1 -= (nums2 << (cnt-1));  
        }  
        return (dividend > 0 ^ divisor > 0)? -ans : ans;  
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值