1. 程式人生 > >Divide Two Integers 兩數相除

Divide Two Integers 兩數相除

給定兩個整數,被除數 dividend 和除數 divisor。將兩數相除,要求不使用乘法、除法和 mod 運算子。

返回被除數 dividend 除以除數 divisor 得到的商。

示例 1:

輸入: dividend = 10, divisor = 3
輸出: 3

示例 2:

輸入: dividend = 7, divisor = -3
輸出: -2

說明:

  • 被除數和除數均為 32 位有符號整數。
  • 除數不為 0。
  • 假設我們的環境只能儲存 32 位有符號整數,其數值範圍是 [−231,  231 − 1]。本題中,如果除法結果溢位,則返回 231 − 1。

思路:首先解釋下基本概念:a/b=c...d,其中a叫dividend(被除數),b叫divisor(除數),c叫商,d叫餘數。如果不能使用乘除以及取餘的操作符,那麼只能用位操作來完成。

首先先把所有數變成正數(除數,被除數),然後根據商是等於被除數除以除數的幾份得到的,所以我們逐次相減來得到。

比如被除數15,除數4,那麼15-4=11>=0,所以把除數的次數*2,變成15-8=7>=0,再把除數的次數*2,變成15-16=-1<0,所以我們只處理到8即可,保留對應的次數(8/4=2次)

被除數變成15-8=7,依然從4開始,7-4=3>=0,所以把除數4*2,7-8=-1<0,所以保留次數1

被除數變成7-4=3,這時由於被除數3小於除數4,所以跳出迴圈,返回次數的累加和2+1=3

這裡還要處理一些邊界條件,比如被除數如果是INT_MIN,如果用abs(INT_MIN)會得到一個負值,所以要用一個long long int來接收,且取絕對值的函式應該變成llabs(INT_MIN),這樣得到的值才是2147483648。

參考程式碼:

class Solution {
public:
    int divide(int dividend, int divisor) {
        if (dividend == INT_MIN) {
            if (abs(divisor) == 1) return divisor == 1 ? INT_MIN : INT_MAX;
        }
        long long didend = llabs(dividend), divs = llabs(divisor),sign=((dividend<0)^(divisor<0))?-1:1;
        int res = 0;
        while (didend >= divs) {
            int time = 1;
            while (didend > (divs << 1)) {
                divs <<= 1;
                time<<=1;
            }
            didend -= divs;
            res += time;
            divs = abs(divisor);
        }
        return sign * res;
    }
};