leetcode 29. Divide Two Integers

题目:

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

If it is overflow, return MAX_INT.

public class Solution {
   public int divide(int dividend, int divisor) {  
        int sign = 1;  
        if(dividend<0) sign = -sign;  
        if(divisor<0) sign = -sign;  
        long temp = Math.abs((long)dividend);  
        long temp2 = Math.abs((long)divisor);  
        long c = 1;  
        while(temp>temp2){  
            temp2 = temp2<<1;  
            c = c<<1;  
        }  
        long res = 0;  
        while(temp>=Math.abs((long)divisor)){  
            while(temp>=temp2){  
                temp-=temp2;  
                res+=c;  
            }  
            temp2 = temp2>>1;  
            c=c>>1;  
        }  
        if(sign>0) 
           { if(res>Integer.MAX_VALUE)
                return Integer.MAX_VALUE;
             else return (int)res;
           }
        else return (int)-res;  

    }  
}
思路是:

     30/5=5*2*2/5 + 5*2/5

    26/5=5*2*2/5+5*1/5

      

回想除法的最朴素思想:

即,当   被除数>除数  一直拿被除数减去除数,能减去除数的次数为两数相除的结果。

根据这个思想,我们很容易写出伪代码:

while(被除数>除数)

被除数  -=  除数

res ++

最终的res为我们所要的结果。

但是,我们考虑最坏情况:当被除数是Integer.MAX_VALUE,除数是1,那么刚刚的代码就要做(2^31-1)次,即2147483647次减法,结果是超时.



那么有一个做法就是通过左移操作减少减法的次数,但事实上循环的次数并没有减少。

左移操作一次相当于乘以2,那么左移N次就相当于乘以2^N。

在这道题上,我们每次减去2^(N) * 除数,再将上述res每次加上 1<<2^N次方,就能大大缩减做减法的次数。

左移操作也解决了题目要求不能使用乘法的限制。

这个N就可以通过内循环左移比较来判断。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值