1. 题目

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

If it is overflow, return MAX_INT.

2. 思路

这题的异常考虑点的坑很多。各种溢出。
先转正,再用二进制移位比较计算。
基本思路就是二进制,用移位和加减法来完成。
按二进制的最高位开始匹配,依次得到二进制下的所有非0位。
注意:正负数的处理。
注意:-max转为正数时会溢出,比如 -max/-1 = max + 1 溢出。
注意:由于做了负数转正,-max不能直接转换为正数。这里会导致溢出得到一个0值,于是就容易死循环了。

3. 代码

耗时:9ms

class Solution {
public:
    int divide(int dividend, int divisor) {
        if (dividend == -2147483648 && divisor == -1) return 2147483647;
        if (dividend == -2147483648 && divisor == 1) return -2147483648;
        
        // @warning: 这里是一个坑,如果不扩展到long long上去,当某一个数为-2147483648时,取负会溢出,于是整体就错误最终导致除0的TLM
        long long de = dividend > 0 ? dividend : -1LL * dividend;
        long long di = divisor > 0 ? divisor : -1LL * divisor;
        
        long long flag = 1;
        if (dividend > 0 && divisor < 0 || dividend < 0 && divisor > 0) flag = -1;
        
        if (de < di) return 0;
        //if (di == 0) return 2147483647;
        
        long long res = 0;
        while (de >= di) {
            long long k = 0;
            long long v = di;
            while (de >= v) {
                v <<= 1;
                k++;
            }
            k--;
            v >>= 1;
            res += (1 << k);
            de -= v;
            if (de < di) {
                return flag * res;
            }
        }
        return res * flag;
    }
};

knzeus
72 声望28 粉丝

行万里路,读万卷书