LeetCode 29. 兩數相除 Divide Two Integers(C語言)
阿新 • • 發佈:2018-12-21
題目描述:
給定兩個整數,被除數 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:移位+遞迴
該題第一個問題是特殊情況的處理,包括INT_MAX
和INT_MIN
的處理、負數轉換成正數、判斷商的正負情況。
另一個問題是如何進行除。已知左移和右移實際上相當於乘2和除2,所以利用左移或者右移來操作。另外主要根據(a+b)/c = a/c + b/c
。比如令a = c * 2^i
,則b
就是剩下的那部分,重新計算b
與c
的商。比如使用右移,右移被除數,直到被除數剛好大於除數,記錄移動的次數i
,此時結果就可以根據移動次數和剩下的那部分來計算商。左移也可以,原理基本一致。
執行時間8ms,程式碼如下。
int myDivide(int dividend, int divisor) {
// printf("%d=%d\n", dividend, divisor);
int m = dividend;
int i = 0, result = 1;
if(dividend < divisor)
return 0;
while(dividend >= divisor) {
i++;
dividend = (dividend >> 1);
}
i--;
result = result << i;
return result + myDivide(m - (divisor << i), divisor);
}
int divide(int dividend, int divisor) {
int result = 0;
if(dividend == INT_MIN && divisor == INT_MIN)
return 1;
else if(dividend == INT_MIN) {
if(divisor > 0)
dividend += divisor;
else
dividend -= divisor;
result = 1;
}
else if(divisor == INT_MIN) {
return 0;
}
bool flag = true; //positive
if(divisor < 0) {
divisor = -divisor;
flag = !flag;
}
if(dividend < 0) {
dividend = -dividend;
flag = !flag;
}
if(dividend < divisor)
return flag ? result : -result;
int t = myDivide(dividend, divisor);
if(t == INT_MAX) {
return flag ? INT_MAX : INT_MIN;
}
result += t;
return flag ? result : -result;
}