29. Divide Two Integers

【题目】

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

If it is overflow, return MAX_INT.


题目两句话,不用乘除模求两个数的除法。我把除法化成减法运算,结果直接TLE了。

后来看了下别人的做法,是把除数用左移来扩大,然后减去扩大之后的部分,重复下去,记录次数,就是 结果了。


代码如下:

class Solution {
public:
    int divide(int dividend, int divisor) {
        if(divisor == 0 || (dividend == INT_MIN && divisor == -1))
            return INT_MAX;
        
        bool native = (dividend < 0) ^ (divisor < 0) ? true : false;
        
        long long dividend1 = labs(dividend);
        long long divisor1 = labs(divisor);
        
        int res = 0;
        while(dividend1 >= divisor1){
            long long tmp = divisor1, count = 1;   //注意每次在此处初始化
            while(dividend1 > (tmp << 1)){
                tmp <<= 1;
                count <<= 1;
            }
            dividend1 -= tmp;
            res += count;    
        }
        
        return native ? -res : res;
    }
};

有几个点需要注意:

1.参数合法性检测。除数不为0自然都知道,但当除数为INT_MIN时,且被除数如果是-1的话,那么得到的结果是INT_MAX+1,会产生溢出

2.使用long long类型来处理溢出。我们计算时需要对被除数和除数的绝对值进行计算这是自然的,如果除数或者被除数为INT_MIN,取绝对值是会产生溢出的,所以直接采用long long类型计算,并且下面的tmp和count也采用long long类型,都是为了避免溢出。

3.算法核心,举个例子吧:15 ÷ 3 

首先我们要提高效率,就要扩大被除数,让我们减法的过程尽可能少。那么就采用左移<<,如果左移结果不大于15就继续左移,此例中我们可以得到左移的序列为:3->6->12,但是左移产生的包含除数3的次数也是移位级别增长的,所以count同时也要左移。并累加结果到res。

此例情况比较特殊,如果出现最后一次左移的结果为x,15-x>3的话,我们需要重新开始左移,count归1,tmp归divisor,重新开始计数,再次累加到res。

如此循环万福,不满足条件跳出循环,即得到正确的结果。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值