劍指Offer_#65_不用加減乘除做加法
阿新 • • 發佈:2020-07-29
劍指Offer_#65_不用加減乘除做加法
劍指offerContents
題目
寫一個函式,求兩個整數之和,要求在函式體內不得使用 “+”、“-”、“*”、“/” 四則運算子號。
示例:
輸入: a = 1, b = 1
輸出: 2
提示:
a,b均可能是負數或 0
結果不會溢位 32 位整數
思路分析
又是一道腦筋急轉彎的題目。不能用加減乘除運算,就只能用二進位制位運算了。
思路是通過二進位制位運算模擬十進位制的加法,加法分為3步:
1. 對應位相加,得到非進位和
- 對於二進位制數字來說,異或運算可以得到非進位和。
- 可以發現最後一位的進位我們沒有計算進去,下一步我們考慮進位。
10001(十進位制的17)
+00101(十進位制的5)
------
10100
2. 計算進位結果,將需要進位的位置標記為1
- 兩個二進位制數字相加,何時產生進位?只有1和1相加會產生進位。我們聯想到
&
運算,只有1和1相&
結果是1。 - 又因為當前位進位是加到更高一位上面的,所以僅僅
&
運算還不夠,還要將運算結果左移一位。
10001
&00101
------
00001 << 1 = 00010
3. 將非進位和與進位部分相加,得到最終結果
- 可以轉換為10進位制數字驗證,相加結果是正確的。
10100
+00010
------
10110(十進位制的22)
解答
class Solution {
public int add(int a, int b) {
int sum;//非進位和
int carry;//進位部分
//b==0說明進位結束,這時的a就是最終結果
while(b != 0){
sum = a ^ b;//異或,結果是非進位和
carry = (a & b) << 1;//與運算後左移一位,結果是進位部分
a = sum;
b = carry;
}
return a;
}
}
複雜度分析
時間複雜度:O(1),最多隻需要進行32次迴圈(即每一位都要進位的情況),是常數
空間複雜度:O(1),只有常數個輔助變數