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
题目是说在不使用+和-的情况下实现两个整数的加法运算
以下为一个在讨论区7.7k view的java答案
<pre name="code" class="java"> public int getSum(int a, int b) {
if (a == 0) return b;
if (b == 0) return a;
while (b != 0) {
int carry = a & b;
a = a ^ b;
b = carry << 1;
}
return a;
}
当时看到这个答案心里也是蒙逼的,并不知道在说些什么,后来通过自己的分析,总结了一下思路。
(1) 模拟加法应该与位运算有关;
(2) 位运算中与加法最为相似的运算是“异或”操作,可以在两位二进制数分别为0和1的时候直接可以看作是进行了加法运算;
(3) 在加法运算中,需要有“进位”操作,如何通过位运算实现“进位”操作?答案当然是通过左移一位来实现;
(4) 如何确定哪些位是需要“进位”的?即哪些位在运算时是要模拟“1+1”的?我们显然需要用“与”运算进行判断,两个整数a和b进行“与”运算后得到的二进制数中位为1的部分就是需要“进位”的部分;
了解了以上思路以后就可以着手编写程序了。
step 1: a和b进行“与”操作得到一个其中包含进位信息的整数,先将其赋值给一个叫做carry的变量备用(其中1代表需要“进位”,0代表不需要“进位”);
step 2: a和b进行“异或”运算,得到的结果是a和b中所有不需要进位的每一位相加的结果,并将该结果复制给a备用(如:0异或1,1异或0,0异或0这三种结果是和0+1,1 + 0,0 + 0得到的结果完全相同的);
step 3: 由于carry中是需要“进位”的位的信息,所以需要将carry整体左移一位表示完成“进位”,将得到的结果赋值给b;
step 4: 若此时b为0,则说明不需要任何“进位”,这表示a和b异或的结果已经等同与a+b的结果,即a和b中不存在1 + 1这种情况了,此时就可以直接输出a作为最后的结果,但是肯定有b不为0的情况,那时我们要怎么办?我们要把新a和新b重新进行步骤1,2,3,直到b的值变为0。所以这里肯定要用到循环,循环条件就是根据b是否为0进行判定。
step 5: 结束循环,a的值就是最后的结果。
这里实际上可以补一个流程图出来,这样理解起来可能更方便,时间有限以后有时间再补~
以下链接就是Leetcode讨论区中该题java版的答案,其中还有减法以及位操作的一些基础扫盲,有兴趣的可以参考一下。
https://discuss.leetcode.com/topic/49771/java-simple-easy-understand-solution-with-explanation