[LeetCode] Divide Two Integers

题目

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

If it is overflow, return MAX_INT.

思路

这道题需要用到移位操作,这就涉及到一些二进制相关的概念,先普及一下:

1)二进制表示中,首位是符号位,1表示负数,0表示正数

2)二进制表示中,java的int是32位,取值范围为[-2^31,2^31-1]

3)移位分为左移和右移,左移<<就是在某个二进制数末位后补0;右移分为逻辑右移>>>和符号右移>>,逻辑右移在这个数的首位前补0,符号右移则在这个数的首位前补符号位

这道题有几个注意点:

1)divisor=0,返回2^31-1

2)处理溢出,当且仅当dividend=-2^31,divisor=-1,这时正确结果应该是2^31,但它超过了int的取值范围,只能返回2^31-1

3)最简单的思路是在dividend中每次减去divisor直到dividend<divisor,但是这样会超时。利用移位操作,divisor<<=1直到divisor>=dividend,这样每次减去的就是2的幂,时间复杂度可以降低到O(logN)

4)将int转化为long,在计算出正确结果后再转化为int

5)用表达式boolean isNegative = (((dividend^divisor)>>>31)==1) ? true : false判断结果正负(先亦或再逻辑右移31位),这样后面操作的dividend和divisor都是正数


代码

public class Solution {
    public int divide(int dividend, int divisor) {
        if(divisor == 0)
            return Integer.MAX_VALUE;
        
        if(dividend == Integer.MIN_VALUE && divisor == -1)
            return Integer.MAX_VALUE;
        
        long result = 0;
        boolean isNegative = (((dividend^divisor)>>>31)==1) ? true : false;
        long dividendL = Math.abs((long)dividend);
        long divisorL = Math.abs((long)divisor);
        
        int digit = 0;
        while(divisorL << 1 <= dividendL){
            divisorL <<= 1;
            digit++;
        }
        while(digit >= 0){
            if(dividendL >= divisorL){
                dividendL -= divisorL;
                result += 1<<digit;
            }
            divisorL >>= 1;
            digit--; 
        }
        return isNegative ? (int)(-result) : (int)result;
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值