問題描述
給定兩個整數,被除數dividend
和除數divisor
。將兩數相除,要求不使用乘法、除法和 mod 運算子。
返回被除數dividend
除以除數divisor
得到的商。
示例 1:
輸入: dividend = 10, divisor = 3示例 2:輸出: 3
輸入: 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說...