剑指Offer.65 不使用四则运算符进行加法运算
剑指 Offer 65. 不用加减乘除做加法
问题:
写一个函数,求两个整数之和,要求在函数体内不得使用 “+”、“-”、“*”、“/” 四则运算符号。
思路:
使用位运算实现加法
一位的加法举例
普通加法 | 异或 |
---|---|
1+1=0 | 1^1=0 (错误) |
1+0=1 | 1^0=1 (正确) |
0+1=1 | 0^1=1 (正确) |
0+0=0 | 0^0=0 (正确) |
可以看到异或的结果不能完全保证与正常的加法结果一致,因为1 1这种特殊情况,本来应该进位,但是异或没有进位
与运算 |
---|
1&1=1 (进位) -> 10 |
1&0=0 (不进位) -> 0 |
0&1=0 (不进位) -> 0 |
0&0=0 (不进位) -> 0 |
把两种运算的结果结合起来就是正常运算的结果
由此可以得到两个表达式:
加法表达式:x ^ y
进位表达式 (x & y) << 1 (0移位对结果没有影响)
二位运算
11 + 01 = 100
位运算过程:
-
按位加: res1 = 11 ^ 01 = 10
-
与运算进位:res2 = (11 & 01) << 1 = 010
-
res1 = res1 ^ res2 = 10 ^ 010 = 000
-
res2 = (res1 & res2) << 1 = (10 & 010) << 1 = 100
-
res1 = 000 ^ 100 = 100
-
res2 = (000 & 100) << 1 = 0000
此时与运算已经没有可以进位的了,res1就是最终结果
更多位的加法运算依次类推
代码
public int Add(int num1,int num2) {
int result = 0;
int carry = 0;
do{
result = num1 ^ num2;
carry = (num1 & num2) << 1;
num1 = result;
num2 = carry;
}while(carry!=0);
return result;
}
复杂度
- 时间复杂度:O(1) //最高执行32次 int大小32位
- 空间复杂度:O(1)