位运算在算法中的经典应用
位运算不仅是底层优化的利器,更是解决特定算法问题的捷径。通过理解二进制层面的操作逻辑,我们往往能在时间与空间复杂度上达成最优解。以下结合六个经典题目,梳理位运算的核心思路与实现细节。
1. 判定字符是否唯一
问题核心: 判断字符串中所有字符是否都不重复。
思路解析: 利用【位图】思想,用一个整数的比特位代表字符状态。对于小写字母,32 位的 int 变量足以覆盖(26 个字母)。若某位为 0,表示该字符未出现;为 1 则表示已出现。
这里有个优化点:如果字符串长度超过 26,根据鸽巢原理,必然有重复字符,可直接返回 false。
class Solution {
public:
bool isUnique(string astr) {
// 利用鸽巢原理优化
if (astr.size() > 26) return false;
int bitmap = 0;
for (auto i : astr) {
int e = i - 'a';
// 先判断字符是否出现过
if (((bitmap >> e) & 1) == 1) return false;
// 把当前字符加入到位图中
bitmap |= (1 << e);
}
return true;
}
};
2. 消失的数字
问题核心: 数组包含 [0, n] 中缺失的一个数,找出它。
思路解析:
异或运算有一个神奇的性质:a ^ a = 0,a ^ 0 = a。如果我们把数组中的所有数字,以及 [0, n] 范围内的所有数字全部异或在一起,成对出现的数字会相互抵消,最终剩下的就是那个缺失的数字。
class Solution {
public:
int missingNumber {
ret = ;
( i : nums) ret ^= i;
( i = ; i <= nums.(); i++) ret ^= i;
ret;
}
};

