leetcode 29 兩數相除

2021-10-01 17:39:47 字數 2504 閱讀 9533

問題描述  

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

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

示例 1:

輸入: dividend = 10, divisor = 3

輸出: 3

示例 2:

輸入: dividend = 7, divisor = -3

輸出: -2

說明:

這個問題涉及到了計算機如何利用邏輯運算和加減法來求得除法,這個問題之前一度困擾了我很久。

/*** 逼近

* 先定符號

* 結果是正是負還是0?

* @param dividend

* @param divisor

* @return

*/public static int divide(int dividend, int divisor)

if (dividend == integer.min_value && divisor == -1)

if (divisor == -1)

if (divisor == 1)

int res = 0, sum = 0;

boolean plus = false;

//同號

if ((dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0))

//將兩個數都變成負數

dividend = dividend > 0 ? ~dividend + 1 : dividend;

divisor = divisor > 0 ? ~divisor + 1 : divisor;

for (int i = 30; i > -1; i--) {

//被加數未溢位 加之後的結果未溢位 加之後的結果小於被除數

int addnum = divisor<>i == divisor && sum + addnum < 0 && sum + addnum >= dividend) {

sum += addnum;

res += plus ? 1《題解(寫**時候的奇怪想法。。。): 

首先進行邊界處理之類的。

一開始我採用了二分法猜數字,首先做乙個記號記錄結果,然後把被除數(dividend)和除數(divisor)都轉換為正數 (資訊加工),這樣結果就一定是在[0,dividend]。

初始化left = 0, right = dividend,mid = dividend << 1;

然後通過for迴圈累加mid次驗證是否符合結果( mid * divisor <= dividend並無法取到比mid更大的mid'去滿足前面條件);

由於平時並不是經常使用二分碰到了以下問題:

二分的邊界問題: 

如何寫出不雜亂的**?

因為常常使用 mid = (left + right)<<1;

故而遺忘了mid還可以向右偏 mid = ((left + right)<<1) + 1;。

因為要保證結果一定在邊界內,故而

left = mid + 1; right = mid - 1;常常不能同時出現(視情況而定吧)。

所以有時候

採用 right = mid - 1; left = mid;這個組合時:

mid = (left + right)<<1; (left + 1 = right) 時候回卡死!

這個時候要mid  = ((left + right)<<1) + 1;(向右偏)

當然這樣的思路寫出來的**的結果就是我掛了。。

for迴圈累加代替乘法實在太慢了!!!

然鵝,這時候我想到了乙個辦法。

divisor * mid 可以寫成 divisor (m0 * 2^31 + m1 * 2^30 + m2 * 2^31 ....+m30 * 2^0)

然後二的m次方這個東西我是可以通過左移來得到的!

於是我興奮地用這個方法驗證mid對不對。

發現很多邊界問題無法解決

例如:之前說的右偏碰到integer.min_value

integer.min_value無法轉換為正數

mid取得太大,資料溢位,本來divisor * mid已經超過了integer.max_value。卻還是幾千。。。

於是我處於崩潰的邊緣。。。

這樣搞下去我要屎了!

然鵝,解手的時候。我想:

我可以把所有數都轉換為負數先啊

我可以不用猜測mid是多少啊

我直接從一步一步逼近被除數就行啦??? 好像真的是。。

例如 :

結果如若為101010111...(32位)

那麼我從頭開始的非符號位開始看能不能加進去就好啦! 如若能加進去就逼近了被除數,資料本身溢位,加進去溢位,加進去大於被除數就代表不能加!

其他的都加,反正我要的也是最逼近的數。。。

LeetCode29 兩數相除

給定兩個整數,被除數dividend和除數divisor。將兩數相除,要求不使用乘法 除法和 mod 運算子。返回被除數dividend除以除數divisor得到的商。示例 1 輸入 dividend 10,divisor 3輸出 3示例 2 輸入 dividend 7,divisor 3輸出 2說...

LeetCode 29 兩數相除

給定兩個整數,被除數dividend和除數divisor。將兩數相除,要求不使用乘法 除法和 mod 運算子。返回被除數dividend除以除數divisor得到的商。示例 1 輸入 dividend 10,divisor 3 輸出 3 示例 2 輸入 dividend 7,divisor 3 輸出...

leetcode 29 兩數相除

給定兩個整數,被除數dividend和除數divisor。將兩數相除,要求不使用乘法 除法和 mod 運算子。返回被除數dividend除以除數divisor得到的商。示例 1 輸入 dividend 10,divisor 3輸出 3示例 2 輸入 dividend 7,divisor 3輸出 2說...