劍指 Offer II 001 整數除法

2022-09-07 18:24:12 字數 1390 閱讀 6068

難度: 簡單

輸入2個int型整數,它們進行除法計算並返回商,要求不得使用乘號*、除號/及求餘符號%。當發生溢位時,返回最大的整數值。假設除數不為0。例如,輸入15和2,輸出15/2的結果,即7。

這個題目限制我們不能使用乘號和除號進行運算。乙個直觀的解法是基於減法實現除法。例如,為了求得15/2的商,可以不斷地從15裡減去2,當減去7個2之後餘數是1,此時不能再減去更多的2,因此15/2的商是7。我們可以用乙個迴圈實現這個過程。

但這個直觀的解法存在乙個問題。當被除數很大但除數很小時,減法操作執行的次數會很多。例如,求\((2^-1 )/1\),減1的操作將執行\(2^-1\)次,需要很長的時間。如果被除數是\(n\),那麼這種解法的時間複雜度為\(o(n)\)。

我們需要對這種解法進行優化。可以將上述解法稍做調整。當被除數大於除數時,繼續比較判斷被除數是否大於除數的2倍,如果是,則繼續判斷被除數是否大於除數的4倍、8倍等。如果被除數最多大於除數的2k倍,那麼將被除數減去除數的2k倍,然後將剩餘的被除數重複前面的步驟。由於每次將除數翻倍,因此優化後的時間複雜度是\(o(logn)\)。(:這裡減去除數的2k倍,而不是k倍,是因為本題ban掉了乘號*,因此要實現被除數減去除數的倍數,只能通過將除數通過自己加自己的方式進行翻倍,即value+=value,所以倍數是2k倍,即2的整數倍。)

下面以15/2為例討論計算的過程。15大於2,也大於2的2倍(即4),還大於2的4倍(即8),但小於2的8倍(即16)。於是先將15減去8,還剩餘7。由於減去的是除數的4倍,減去這部分對應的商是4。接下來對剩餘的7和除數2進行比較,7大於2,大於2的2倍(即4),但小於2的4倍(即8),於是將7減去4,還剩餘3。這一次減去的是除數2的2倍,對應的商是2。然後對剩餘的3和除數2進行比較,3大於2,但小於2的2倍(即4),於是將3減去2,還剩餘1。這一次減去的是除數的1倍,對應的商是1。最後剩餘的數字是1,比除數小,不能再減去除數了。於是15/2的商是4+2+1,即7。

一些細節

class solution 

if(b>0)

//這裡將運算雙方轉為負數相除,因為負數的絕對值比正數的絕對值大1,所有運算範圍比正數大

int res=dividenegative(a,b);

return negative==1?-res:res;

}//定義兩個負數的除法運算

public int dividenegative(int a,int b)

res+=times;

a-=value;

}return res;

}}

劍指 Offer II 001 整數除法

為了方便描述,我們考慮a和b都為正數的情況,之後再考慮其他情況。最直接的思路就是將b乙個乙個的累加,至到累加的結果超過了a,即可得到答案。以a 18,b 5為例,此過程如下圖所示 這個作法通俗易懂,但效率不高,舉個極端例子,當a 2 31 1 b 1時,要將b加2 31 1次才能算出結果。下面給出優...

劍指Offer II 左旋轉字串

字串的左旋轉操作是把字串前面的若干個字元轉移到字串的尾部。請定義乙個函式實現字串左旋轉操作的功能。比如,輸入字串 abcdefg 和數字2,該函式將返回左旋轉兩位得到的結果 cdefgab 一行 沒什麼好說的,複習substr用法 形式 s.substr pos,n 解釋 返回乙個string,包含...

劍指Offer II 0 n 1中缺失的數字

乙個長度為n 1的遞增排序陣列中的所有數字都是唯一的,並且每個數字都在範圍0 n 1之內。在範圍0 n 1內的n個數字中有且只有乙個數字不在該陣列中,請找出這個數字。兩種思路都試一下,現在就能更明確力扣的判時就假的一批。二分法竟然比順序找還慢 重點說下二分法的思路 演算法解析 返回值 跳出時,變數 ...