算法实战:位运算解决两数之和、唯一数字及缺失数字
位运算是算法面试中的高频考点,它不仅能优化空间复杂度,往往还能将时间复杂度降至线性。今天我们来深入探讨三道经典的位运算题目,看看如何巧妙利用二进制特性解决问题。
35. 两个整数之和
题目描述
不使用运算符 + 和 -,计算两整数 a、b 之和。
核心思路
在计算机底层,加法本质上是无进位加法与进位的叠加。
- 异或(^):相当于无进位加法。例如
1 ^ 1 = 0,1 ^ 0 = 1,这与二进制加法中不考虑进位的结果一致。 - 按位与(&)左移(<<):用于计算进位。只有当两个位都为 1 时才会产生进位,且进位需要向左移动一位才能加到下一位上。
我们需要不断重复这两个步骤,直到没有进位为止。这个过程其实就是在模拟硬件电路中的加法器逻辑。
代码实现
class Solution {
public:
int getSum(int a, int b) {
// 当进位不为 0 时,继续循环
while (b != 0) {
// 无进位相加的结果
int x = a ^ b;
// 计算进位位置,并左移
int y = (a & b) << 1;
// 更新 a 为无进位结果,b 为新的进位
a = x;
b = y;
}
return a;
}
};
注意:循环结束时
b必定为 0,此时a即为最终结果。原代码末尾的return a ^ b在b=0时等价于return a,但直接返回a语义更清晰。
36. 只出现一次的数字 II
题目描述
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。
核心思路
这道题如果直接用哈希表统计,空间复杂度是 O(N)。利用位运算可以将空间复杂度降为 O(1)。
既然其他数字都出现了三次,那么对于任意一个比特位,所有数字在该位上的 1 出现的总次数应该是 3 的倍数。唯独那个只出现一次的数字,会使得某一位上的 1 的总数模 3 余 1。
因此,我们可以遍历整数的 32 个比特位,统计每一位上 1 出现的总次数,然后对 3 取模。如果余数为 1,说明目标数字在该位上是 1,否则是 0。


