题目来源:LeetCode 371: 两整数之和
问题抽象: 给定两个整数 a
和 b
(32 位有符号整数,值域 -2³¹ ≤ a, b ≤ 2³¹-1
),要求计算两数之和 a + b
,满足以下核心需求:
-
操作限制:
- 禁止使用 算术运算符
+
和-
(包括++
、--
、复合赋值运算符等); - 仅允许使用位运算(如
&
、|
、^
、<<
、>>
)实现加法逻辑。
- 禁止使用 算术运算符
-
计算规则:
- 通过 位运算模拟二进制加法:
- 无进位加和:
a ^ b
(异或); - 进位值:
(a & b) << 1
(与运算后左移); - 迭代计算:将 加和值 与 进位值 作为新输入,直至进位为
0
。
- 无进位加和:
- 通过 位运算模拟二进制加法:
-
数学本质:
- 位运算需正确处理 补码表示(负数同样适用);
- 迭代过程等价于硬件加法器的 进位传递。
-
边界处理:
- 零值处理:
a=0
时返回b
,b=0
时返回a
; - 正负数混合:
a=1, b=2
→3
;a=-1, b=1
→0
(补码运算:0xFFFFFFFF ^ 0x00000001 = 0
);
- 溢出处理:
- 输入为
2147483647
和1
时,输出-2147483648
(补码溢出); - 输入为
-2147483648
和-1
时,输出2147483647
(反向溢出);
- 输入为
- 大数验证:
a=123456, b=987654
→1111110
。
- 零值处理:
输入:整数 a
,整数 b
(32 位有符号整数)。
输出:整数 sum
(a + b
的结果,允许按补码规则溢出)。
解题思路
题目要求在不使用运算符 +
和 -
的情况下计算两整数之和。核心思路是利用位运算模拟二进制加法过程:
- 异或运算:
a ^ b
得到无进位加法结果(忽略进位)。 - 与运算 + 左移:
(a & b) << 1
计算进位值。 - 迭代相加:将无进位结果与进位值重复上述操作,直到进位值为0。
- 终止条件:当进位值归零时,无进位结果即为最终和。
示例分析(5 + 7 = 12):
- 初始:a=5 (
0101
), b=7 (0111
) - 第一步:
- 无进位加法:
0101 ^ 0111 = 0010
(2) - 进位计算:
(0101 & 0111) << 1 = 1010
(10)
- 无进位加法:
- 第二步:
- 无进位加法:
0010 ^ 1010 = 1000
(8) - 进位计算:
(0010 & 1010) << 1 = 0100
(4)
- 无进位加法:
- 第三步:
- 无进位加法:
1000 ^ 0100 = 1100
(12) - 进位计算:
(1000 & 0100) << 1 = 0000
(0) → 终止
- 无进位加法:
代码实现(Java版)🔥点击下载源码
class Solution {
public int getSum(int a, int b) {
while (b != 0) { // 当进位为0时终止循环
int carry = (a & b) << 1; // 计算进位值
a = a ^ b; // 计算无进位加法结果
b = carry; // 将进位值赋给b,下一轮迭代
}
return a; // 返回最终结果
}
}
代码说明
- 循环条件:
b != 0
确保当进位值归零时退出循环。 - 进位计算:
(a & b) << 1
通过位与运算获取进位位置,左移1位实现进位。 - 无进位加法:
a ^ b
通过异或运算得到忽略进位的中间结果。 - 变量更新:每轮迭代将无进位结果赋给
a
,进位值赋给b
,循环处理进位叠加。
时间复杂度:O(1),最多处理32位(整型位数)。空间复杂度:O(1),仅使用常数级额外空间。