剑指 Offer 65. 不用加减乘除做加法 - 力扣(LeetCode)
十进制加法:
1998
+
0624
=
2622
1998+0624=2622
1998+0624=2622
不考虑进位
1998
+
0624
=
1512
1998+0624=1512
1998+0624=1512
只考虑进位
8
+
4
=
10
8+4=10
8+4=10
90
+
20
=
100
90+20=100
90+20=100
900
+
600
=
1000
900+600=1000
900+600=1000
总和:
1512
+
10
+
100
+
1000
=
2622
1512+10+100+1000=2622
1512+10+100+1000=2622
二进制:
1001
+
1011
=
00010100
1001+1011=0001 0100
1001+1011=00010100
不考虑进位
1001
+
1011
=
0010
1001+1011=0010
1001+1011=0010
只考虑进位
0001
+
0001
=
0010
0001+0001=0010
0001+0001=0010
1000
+
1000
=
00010000
1000+1000=0001 0000
1000+1000=00010000
总和:
0010
+
0010
+
00010000
=
00010100
0010+0010 + 0001 0000=0001 0100
0010+0010+00010000=00010100
结论:
a
+
b
a+b
a+b的和为不考虑进位结果
+
+
+只考虑进位和结果
容易看出
不考虑进位结果:
a
⊕
b
a\oplus b
a⊕b
只考虑进位和结果:
(
a
&
b
)
<
<
1
(a\&b)<<1
(a&b)<<1
还有一个加号怎么处理,递归!
所以容易写出递归代码
class Solution {
public:
int add(int a, int b) {
if(a == 0)
return b;
else if(b == 0)
return a;
return add(a ^ b, (unsigned int)(a & b) << 1);
}
};
容易发现这是一个尾递归,可以改为迭代。
class Solution {
public:
int add(int a, int b) {
while(a != 0 && b != 0){
int left = a ^ b;
int right = (unsigned int)(a & b) << 1;
a = left;
b = right;
}
if(a == 0)
return b;
else if(b == 0)
return a;
return 0;
}
};