For given numbers a and b in function aplusb, return the sum of them. Note You don't need to parse the input and output. Just calculate and return. Example If a=1 and b=2 return 3 Challenge Can you do it with out + operation? Clarification Are a and b both 32-bit integers? - Yes.
直接+沒什么好說的,關鍵在於不用+的操作:
考驗Bit Operation, 可以用按位^異或兩個操作數對應位以及carry,只是carry是1還是0需要分情況討論。求更優的解法
1 class Solution { 2 /* 3 * param a: The first integer 4 * param b: The second integer 5 * return: The sum of a and b 6 */ 7 public int aplusb(int a, int b) { 8 // Click submit, you will get Accepted! 9 int i = 0; 10 int res = 0; 11 int carry = 0; 12 for (; i<32; i++) { 13 int aa = (a >> i) & 1; 14 int bb = (b >> i) & 1; 15 res |= (aa ^ bb ^ carry) << i; 16 if (aa == 1 && bb == 1 || ((aa ==1 || bb == 1) && carry == 1)) { 17 carry = 1; 18 } 19 else carry = 0; 20 } 21 return res; 22 } 23 };
貼一個別人的簡潔思路:
位運算實現整數加法本質就是用二進制進行運算。
其主要用了兩個基本表達式:
x^y //執行加法,不考慮進位。
(x&y)<<1 //進位操作
令x=x^y ;y=(x&y)<<1 進行迭代,每迭代一次進位操作右面就多一位0,最多需要“加數二進制位長度”次迭代就沒有進位了,此時x^y的值就是結果。
我們來做個3位數的加法:
101+011=1000 //正常加法
位運算加法:
(1) 101 ^ 011 = 110
(101 & 011)<<1 = 010
(2) 110 ^ 010 = 100
(110 & 010)<<1 = 100
(3) 100 ^ 100 = 000
(100 & 100)<<1 = 1000
此時進行相加操作就沒有進位了,即000 ^ 1000=1000即是最后結果。
1 class Solution { 2 /* 3 * param a: The first integer 4 * param b: The second integer 5 * return: The sum of a and b 6 */ 7 public int aplusb(int a, int b) { 8 while(b != 0){ 9 int carry = a & b; 10 a = a ^ b; 11 b = carry << 1; 12 } 13 return a; 14 } 15 }
或者用Recursion寫:
1 public int aplusb(int a, int b) { 2 // Click submit, you will get Accepted! 3 if (b == 0) return a; 4 int sum = a^b; 5 int carry = (a&b)<<1; 6 return aplusb(sum, carry); 7 }