[LeetCode] Divide Two Integers 兩數相除

Grandyang發表於2015-04-16

 

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

If it is overflow, return MAX_INT.

 

這道題讓我們求兩數相除,而且規定我們不能用乘法,除法和取餘操作,那麼我們還可以用另一神器位操作Bit Operation,思路是,如果被除數大於或等於除數,則進行如下迴圈,定義變數t等於除數,定義計數p,當t的兩倍小於等於被除數時,進行如下迴圈,t擴大一倍,p擴大一倍,然後更新res和m。這道題的OJ給的一些test case非常的討厭,因為輸入的都是int型,比如被除數是-2147483648,在int範圍內,當除數是-1時,結果就超出了int範圍,需要返回INT_MAX,所以對於這種情況我們就在開始用if判定,將其和除數為0的情況放一起判定,返回INT_MAX。然後我們還要根據被除數和除數的正負來確定返回值的正負,這裡我們採用長整型long來完成所有的計算,最後返回值乘以符號即可,程式碼如下:

 

解法一:

class Solution {
public:
    int divide(int dividend, int divisor) {
        if (divisor == 0 || (dividend == INT_MIN && divisor == -1)) return INT_MAX;
        long long m = abs((long long)dividend), n = abs((long long)divisor), res = 0;
        int sign = ((dividend < 0) ^ (divisor < 0)) ? -1 : 1;
        if (n == 1) return sign == 1 ? m : -m;
        while (m >= n) {
            long long t = n, p = 1;
            while (m >= (t << 1)) {
                t <<= 1;
                p <<= 1;
            }
            res += p;
            m -= t;
        }
        return sign == 1 ? res : -res;
    }
};

 

我們可以使上面的解法變得更加簡潔:

 

解法二:

class Solution {
public:
    int divide(int dividend, int divisor) {
        long long m = abs((long long)dividend), n = abs((long long)divisor), res = 0;
        if (m < n) return 0;    
        while (m >= n) {
            long long t = n, p = 1;
            while (m > (t << 1)) {
                t <<= 1;
                p <<= 1;
            }
            res += p;
            m -= t;
        }
        if ((dividend < 0) ^ (divisor < 0)) res = -res;
        return res > INT_MAX ? INT_MAX : res;
    }
};

 

我們也可以通過遞迴的方法來解,思路都一樣:

 

解法三:

class Solution {
public:
    int divide(int dividend, int divisor) {
        long long res = 0;
        long long m = abs((long long)dividend), n = abs((long long)divisor);
        if (m < n) return 0;
        long long t = n, p = 1;
        while (m > (t << 1)) {
            t <<= 1;
            p <<= 1;
        }
        res += p + divide(m - t, n);
        if ((dividend < 0) ^ (divisor < 0)) res = -res;
        return res > INT_MAX ? INT_MAX : res;
    }
};

 

參考資料:

https://discuss.leetcode.com/topic/38191/summary-of-3-c-solutions

https://discuss.leetcode.com/topic/3421/simple-o-log-n-2-c-solution

https://discuss.leetcode.com/topic/15568/detailed-explained-8ms-c-solution/2

 

LeetCode All in One 題目講解彙總(持續更新中...)

相關文章