Calculate the sum of two integers a and b, but you are not allowed to use the operator +
and -
.
Example:
Given a = 1 and b = 2, return 3.
class Solution {
public:
int getSum(int a, int b) {
}
};
先上答案:
class Solution {
public:
int getSum(int a, int b) {
int result=a^b;
int carry=(a&b)<<1;
if(carry!=0)
return getSum(result,carry);
else
return result;
}
};
解释:
加法运算,不管是二进制加法还是日常的十进制加法,我们正常的算术是从最低位开始算,然后如果有进位就进一,依次到最高位。
其实这里我们可以转换一下思维,用另一种方式,那就是不在从低位到高位的计算过程中算进位,而是先算出没有进位的结果,最后再加上进位。
举个例子:257+348=605=595+010,其中595代表没有进位的结果,010代表对应位置的进位。
而没有进位的结果等于257XOR348,异或在C++中用^表示;对应进位为257&348(转换成二进制比较好想一些)。
于是任意的A+B就可以转换成A^B+A&B,所以函数原本传进来A,B,我们现在可以传A^B,A&B,递归。
1.如果进位为0,我们直接返回result的值就可以了。
2.如果进位不是0,则需要运行result+carry(进位不为0当然要加进位啊),即递归调用加法。
这里A^B运算其实已经在运行加法了,这是精髓,只是把进位单剔出来了。十进制下(二进制也一样),如果数字不是9,那么这位置可以“吸进来一个进位”;如果是9,那么它下一次就是0,在下一次就可以吸进位了。所以,总会得到carry为0的情况,即所有进位被吸光。也就是到了1情况。