【leetcode】29. Divide Two Integers 不能使用乘除法的整數除法

knzeus發表於2019-05-11

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;
    }
};

相關文章