这是 LeetCode 上 2021-9-26 的每日一题:「371. 两整数之和」
1. 题目描述
给你两个整数 a
和 b
,不使用 运算符 +
和 -
,计算并返回两整数之和。
示例:
输入:a = 1, b = 2
输出:3
2. 解答
对于位运算中的加法,只有四种情况:
0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
1 + 1 = 0(进位 1)
总结规律可得,对于a
、b
,不考虑进位的加法 = a^b
。
例如,对于a=2
,b=3
:
a = 0010
b = 0011
a ^ b:
0 0 1 0
0 0 1 1
-------
0 0 0 1
在位运算中,进位可以有与得到:
a = 0010
b = 0011
a & b:
0 0 1 0
0 0 1 1
-------
0 0 1 0
得到的0010
并不是真正的进位,进位1
需要在更高一位上,故左移一位即可得到0100
。
那么将不考虑进位的加法加上进位即可得到结果:
0 0 0 1
0 1 0 0
-------
0 1 0 1 (5)
若相加后还有进位的话,将a^b
的结果与进位继续进行上述操作,直到没有进位为止。
总结一下,对于给定的a
和b
:
- 不考虑进位的加法:
a^b
- 进位:
(a & b) << 1
那么不断地将进位再次与不考虑进位的加法结果作相同的运算,直到进位为0
即可。
容易写出以下代码。
1. 迭代
const getSum = (a, b) => {
while (b) {
// 进位
const c = (a & b) << 1;
// 不考虑进位的加法
a ^= b;
// 将进位赋值给b
b = c;
}
return a;
};
2. 递归
也可以用递归实现:
const getSum = (a, b) => {
if (!b) return a;
return getSum(a ^ b, (a & b) << 1);
};
简单一点也可以:
const getSum = (a, b) => (b ? getSum(a ^ b, (a & b) << 1) : a);
😄最近新创建了个开源仓库,总结 LeetCode 的每日一题,目前已有 C++、JavaScript 语言版本,欢迎大家提供其他语言版本!
🖥️仓库地址:「每日一题系列」