lintcode 中等题:A + B Problem A + B 问题
題目:
中等?A + B 問題
給出兩個整數a和b, 求他們的和, 但不能使用?+?等數學運算符。
如果?a=1?并且?b=2,返回3
注意你不需要從輸入流讀入數據,只需要根據aplusb的兩個參數a和b,計算他們的和并返回就行。
挑戰顯然你可以直接 return a + b,但是你是否可以挑戰一下不這樣做?
說明a和b都是?32位?整數么?
- 是的
我可以使用位運算符么?
- 當然可以?
解題
上面提示了用位運算,通過不能夠用加法,應該也會用到邏輯運算,感覺應該提取a、b的每位數據進行計算,也就是:a1 = a & 1 ,b1 = b & 1 這個就把a、b的最低位提取出來了,同時在進行下一位計算的時候a、b要右移一位,也就是 a = a>> 1 、b = b>> 1,下面問題是中間該怎么搞?參考博客。
a1、b1是a、b的對應位,carry1上一位的進位數,carry2是這一位的進位數,val是a1、b1、carry的和,計算結果有下表:
| a1 | b1 | carry1 | carry1 | val |
| 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 | 1 |
| 0 | 1 | 0 | 0 | 1 |
| 1 | 0 | 0 | 0 | 1 |
| 1 | 1 | 1 | 1 | 1 |
| 1 | 1 | 0 | 1 | 0 |
| 1 | 0 | 1 | 1 | 0 |
| 0 | 1 | 1 | 1 | 0 |
下面即簡單又不簡單
val是第i位的數,carry2是要進位的數,下一輪循環將會代替carry1
val應該在第i位,左移i位可以解決問題,val = val << i
sum 用來保存結果,初始值是 0 ,sum和val進行或運算,<只要有一個1 就是1>,在進行地位運算的時候,高位都是0,也就是主要判斷val的值是不是1的問題,sum = sum | val??
這里的過程還真的不好想的
下一輪循環就是 a = a >> 1 b = b >> 1
Java程序:
class Solution {/** param a: The first integer* param b: The second integer* return: The sum of a and b*/public int aplusb(int a, int b) {// write your code here, try to do it without arithmetic operators.int sum = 0 ;int carry = 0;for(int i = 0;i< 32 ;i++){int a1 = a & 1;int b1 = b & 1;int val = 0 ;if(a1 == 0 && b1 == 0 && carry == 0){val = 0;carry = 0;}else if(a1 == 1 && b1 == 1 && carry == 1){val = 1;carry = 1;}else if(a1==0 && b1 ==0 || a1 ==0 && carry ==0 || b1 ==0 && carry ==0){val = 1;carry = 0;}else{val = 0;carry = 1;}val = val << i;sum = sum | val;a = a >> 1;b = b >> 1;}return sum;} }; View Code總耗時:?660?ms
Python程序:
class Solution:"""@param a: The first integer@param b: The second integer@return: The sum of a and b"""def aplusb(self, a, b):# write your code here, try to do it without arithmetic operators.sum = 0 carry = 0for i in range(32):a1 = a & 1b1 = b & 1val = 0if a1== 0 and b1 ==0 and carry ==0:val =0carry = 0elif a1 == 1 and b1 == 1 and carry ==1:val =1 carry =1elif a1 == 0 and b1 ==0 or a1==0 and carry ==0 or b1 ==0 and carry ==0:val = 1carry = 0else:val = 0carry = 1val = val << isum = sum|vala = a>>1b = b>>1return sum View Code總耗時:?203?ms
這樣寫還是很好理解的,在上面的博客鏈接中,還有另外一種方法,比較不好理解。
異或運算^ 與運算 &? 加法運算<考慮進位> 加法運算<不考慮進位>
0 ^ 0 = 0 0 & 0 = 0 0 + 0 = 0 0 + 0 = 0
1 ^ 0 = 1 1 & 0 = ?0 ?1 + 0 = ?1 1 + 0 = 1
1 ^ 1 = 0 1 & 1 = 1 1 + 1 = 10 1 + 1 = 0
0 ^ 1 = 1 0 & 1 = 0 0 + 1 = 1 ?0 + 1 = 1
可以看出加法不考慮進位的情況下和異或運算結果是一樣的。
與運算結果是1時候,表示要進位 1.為了更好的計算,左移一位,這個就是要進位的,進位的在和上面的結果相加,出現了遞歸的現象了。
?sum = a ^ b
?carry= a&b
a = sum
b = carry
遞歸下去。。。 a b中有0的時候結束
OK
Java程序:
class Solution {/** param a: The first integer* param b: The second integer* return: The sum of a and b*/public int aplusb(int a, int b) {// write your code here, try to do it without arithmetic operators.if(b==0)return a;return aplusb( a ^ b,(a&b)<<1); } }; View Code總耗時:?586?ms
非遞歸程序:
class Solution {/** param a: The first integer* param b: The second integer* return: The sum of a and b*/public int aplusb(int a, int b) {// write your code here, try to do it without arithmetic operators.if(b==0)return a;while(b!=0){int sum = a ^ b;int carry = (a&b)<<1 ;a = sum;b = carry;}return a;} }; View Code總耗時:?592?ms
上面中b后來被考慮成進位項,當所有位都沒有進位時候也就是b ==0 的時候結束程序。
注意在遞歸程序中:不應該增加a==0的時候結束程序,可能出現a =0但是會進位的情況。
上面程序無論是遞歸還是非遞歸都是出現時間超時的問題。
?
class Solution:"""@param a: The first integer@param b: The second integer@return: The sum of a and b"""def aplusb(self, a, b):# write your code here, try to do it without arithmetic operators.if b == 0:return aif a == 0:return bwhile b!=0:carry = (a&b)<<1 a = a ^ bb = carryreturn a View Code?
?
?
?都是這個數據的問題
?
總結
以上是生活随笔為你收集整理的lintcode 中等题:A + B Problem A + B 问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一个球从100 米高的自由落下的反弹高度
- 下一篇: eclipse总是自动跳到ThreadP