1. 程式人生 > 實用技巧 >劍指Offer_#65_不用加減乘除做加法

劍指Offer_#65_不用加減乘除做加法

劍指Offer_#65_不用加減乘除做加法

劍指offer

Contents

題目

寫一個函式,求兩個整數之和,要求在函式體內不得使用 “+”、“-”、“*”、“/” 四則運算子號。

示例:
輸入: 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),只有常數個輔助變數