Leetcode 29 Divide Two Integers 位操作的巧妙运用

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

If it is overflow, return MAX_INT.

题意很简单,实现两数除法,但是不能用乘法,除法和取模。

怎么样?第一感觉就是用减法,但是被除数很大,除数为1的时候肯定会超时,

那就模拟手工除法,按位减呗,这样每一位减的次数最多不会超过10次,

很好,问题又来了,在不允许乘除取模的情况下,如何获取高位?

卡住了。。。

我想了一种列出10,100,1000....位表的方法,通过对每一位反复减去对应位表的数的操作获取每一位的数字,可是这种方法实现起来细节太过繁琐了。

我看了一下discuss,他们用了一种类似进制转换的方法,用位操作代替了*2的操作,想法很好,

其实本质也是模拟除法,只不过它以除数为基,每次扩大为原来的两倍,精髓在于能想到位操作。

注意溢出的边界和中间变量的类型,已标在代码中。

class Solution {
public:
    int divide(int dividend, int divisor) {
        if(divisor==0 || (dividend == INT_MIN && divisor == -1)) return INT_MAX;//两种溢出的情况
        int flag1=dividend<0?-1:1,flag2=divisor<0?-1:1;
        int pre=flag1==flag2?1:-1;
        long long dividend2=flag1==1?dividend:-(long long)dividend; //转正数,int类型在INT_MIN值下会炸
        long long divisor2=flag2==1?divisor:-(long long)divisor;
        int result=0;
        while(dividend2>=divisor2) 
        {
            long long rm=divisor2,base=1;
            while(dividend2>=rm)
            {
                rm<<=1;
                base<<=1;
            }
            rm>>=1;
            base>>=1;
            dividend2-=rm;
            result+=base;
        }
        result=pre==1?result:-result; //符号
        return result;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值