1. 程式人生 > >LeetCode 29. 兩數相除 Divide Two Integers(C語言)

LeetCode 29. 兩數相除 Divide Two Integers(C語言)

題目描述:

給定兩個整數,被除數 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。

題目解答:

方法1:移位+遞迴

該題第一個問題是特殊情況的處理,包括INT_MAXINT_MIN的處理、負數轉換成正數、判斷商的正負情況。
另一個問題是如何進行除。已知左移和右移實際上相當於乘2和除2,所以利用左移或者右移來操作。另外主要根據(a+b)/c = a/c + b/c。比如令a = c * 2^i,則b就是剩下的那部分,重新計算bc的商。比如使用右移,右移被除數,直到被除數剛好大於除數,記錄移動的次數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; }