【位运算】位运算 进阶 典型例子及其深度解析
·
大厂面试中的位运算进阶题目通常涉及更复杂的位操作技巧、空间优化和数学性质应用。以下是3个典型例子及其深度解析:
⚙️ 1. 只出现一次的数字 III(力扣260)
题目描述:数组中恰好有两个元素出现一次,其余均出现两次。要求线性时间、常数空间找出这两个数。
示例:输入: [1,2,1,3,2,5] 输出: [3,5]
核心难点:
两个单身狗元素(设为 a 和 b)的异或结果 a^b 会混合两者的差异位,但无法直接分离 a 和 b。
解法步骤:
- 全局异或:遍历数组得到
diff = a^b。 - 提取最右侧1:
lowbit = diff & -diff,定位a和b二进制中首次不同的位。 - 分组异或:
- 将数组中所有数字根据
num & lowbit是否为0分为两组。 - 每组内分别异或,最终得到
a和b。
- 将数组中所有数字根据
位运算技巧:
diff & -diff:利用补码性质快速提取最右侧1(Lowbit)。- 分组依据:
a和b在lowbit位必然不同,因此会被分到不同组,且重复元素一定成对进入同一组。
代码示例(C++):
vector<int> singleNumber(vector<int>& nums) {
long diff = 0;
for (int num : nums) diff ^= num;
long lowbit = diff & -diff;
vector<int> res(2, 0);
for (int num : nums) {
if (num & lowbit) res[0] ^= num;
else res[1] ^= num;
}
return res;
}
🔍 2. 判定字符是否唯一(面试题01.01)
题目描述:实现算法确定字符串所有字符是否唯一(不额外使用数据结构)。
示例:输入: "leetcode" 输出: false
核心难点:
仅使用常数空间(如一个整数)代替哈希表,检测重复字符。
解法步骤:
- 位掩码标记:用32位整型
bits的每一位表示一个字母(小写字母仅26个)。 - 遍历检查:
- 计算字符偏移
offset = ch - 'a'。 - 若
bits的第offset位已为1,返回false;否则置位bits |= (1 << offset)。
- 计算字符偏移
位运算技巧:
- 鸽巢优化:若字符串长度 > 26,直接返回
false(抽屉原理)。 - 位操作:
- 检查:
(bits >> offset) & 1 - 置位:
bits |= (1 << offset)。
- 检查:
代码示例(Python):
def isUnique(astr: str) -> bool:
if len(astr) > 26:
return False
bits = 0
for ch in astr:
offset = ord(ch) - ord('a')
if (bits >> offset) & 1:
return False
bits |= (1 << offset)
return True
⚡️ 3. 判断4的幂(力扣342)
题目描述:判断整数是否为4的幂次方(不使用循环/递归)。
示例:输入: 16 输出: true
核心难点:
区分4的幂(如4、16)和2的幂(如2、8),后者不一定是4的幂。
解法步骤:
- 先验证是2的幂:
n > 0 && (n & (n-1)) == 0。 - 检查1的位置:4的幂的二进制中,1必须出现在奇数位(从右起第1、3、5…位)。
位运算技巧:
- 奇数位掩码:
0x55555555(十六进制)对应二进制01010101...,用于筛选奇数位。 - 最终条件:
(n & 0x55555555) != 0,确保1不在偶数位。
数学原理:
4^k = (22)k = 2^{2k},其二进制中1的位置必为奇数位(如16=10000,1在第5位)。
代码示例(Java):
boolean isPowerOfFour(int n) {
return n > 0 &&
(n & (n - 1)) == 0 &&
(n & 0x55555555) != 0;
}
💎 大厂面试考点总结
- 位掩码高级应用:
- 状态压缩(如字符唯一性检测)。
- 硬件寄存器操作(嵌入式系统考点)。
- 数学性质结合位运算:
- 4的幂需同时满足2的幂和特定1的位置。
- 空间优化技巧:
- 用整数代替哈希表(字符唯一性)。
- 分组异或分离变量(双单身狗问题)。
💡 提示:面试中需特别注意 语言差异(如Java无无符号类型)和 边界条件(负数、溢出),例如右移时优先使用无符号移位(
>>>)避免符号扩展问题。
更多推荐


所有评论(0)