371. 两整数之和
题目描述
给你两个整数 a
和 b
,不使用 运算符 +
和 -
,计算并返回两整数之和。
示例 1:
输入:a = 1, b = 2 输出:3
示例 2:
输入:a = 2, b = 3 输出:5
提示:
-1000 <= a, b <= 1000
解法
方法一:位运算
两数字的二进制形式 a,b ,求和 s = a + b ,a(i)、b(i) 分别表示 a、b 的第 i 个二进制位。一共有 4 种情况:
a(i) |
b(i) |
不进位的和 |
进位 |
---|---|---|---|
0 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
1 |
0 |
1 |
观察可以发现,“不进位的和”与“异或运算”有相同规律,而进位则与“与”运算规律相同,并且需要左移一位。
对两数进行按位
^
异或运算,得到不进位的和;对两数进行按位
&
与运算,然后左移一位,得到进位;问题转换为求:“不进位的数 + 进位” 之和;
循环,直至进位为 0,返回不进位的数即可(也可以用递归实现)。
时间复杂度 $O(\log n)$。
Python3
class Solution:
def getSum(self, a: int, b: int) -> int:
a, b = a & 0xFFFFFFFF, b & 0xFFFFFFFF
while b:
carry = ((a & b) << 1) & 0xFFFFFFFF
a, b = a ^ b, carry
return a if a < 0x80000000 else ~(a ^ 0xFFFFFFFF)
Java
class Solution {
public int getSum(int a, int b) {
return b == 0 ? a : getSum(a ^ b, (a & b) << 1);
}
}
C++
class Solution {
public:
int getSum(int a, int b) {
while (b) {
unsigned int carry = (unsigned int) (a & b) << 1;
a = a ^ b;
b = carry;
}
return a;
}
};
Go
func getSum(a int, b int) int {
for b != 0 {
s := a ^ b
b = (a & b) << 1
a = s
}
return a
}