💡位操作实战:配对交换(交换奇偶位)
在日常编码和算法面试中,**位操作(bit manipulation)**是一项非常重要但常被忽视的技能。这篇文章将介绍一个非常典型的位操作题:交换一个整数的奇数位和偶数位(配对交换),并用最简洁高效的方式实现它。
📌题目描述
配对交换:给定一个整数 num,交换其所有的奇数位和偶数位。
换句话说:
- 位
0与位1交换; - 位
2与位3交换; - 以此类推……
最终返回交换后的整数。
✅输入输出示例
示例 1:
输入:num = 2 (即二进制 0b10)
输出:1 (即二进制 0b01)
示例 2:
输入:num = 3 (即二进制 0b11)
输出:3 (即二进制 0b11,交换后不变)
🔍解题分析
📎目标
将一个整数的所有相邻二进制位进行两两交换。
以32位整数为例,从最低位开始,每一对位像这样:
位号: ... 5 4 3 2 1 0
值: ... x x x x x x
\ / \ / \ /
交换后变为:
/ \ / \ / \
📎思路拆解
要交换相邻位,有两个关键操作:
- 分离奇偶位
-
- 奇数位掩码(
0x55555555)是:01010101...0101(32位) - 偶数位掩码(
0xAAAAAAAA)是:10101010...1010(32位)
- 奇数位掩码(
- 位移后组合
-
- 将奇数位左移一位(变为偶数位);
- 将偶数位右移一位(变为奇数位);
- 使用按位或(
|)操作将它们合并。
💻解题代码
下面是使用 Python 编写的高效解法:
class Solution:
def exchangeBits(self, num: int) -> int:
# 提取偶数位(如0、2、4...)掩码为0xAAAAAAAA
even_bits = num & 0xAAAAAAAA
# 提取奇数位(如1、3、5...)掩码为0x55555555
odd_bits = num & 0x55555555
# 偶数位右移,奇数位左移后合并
return (even_bits >> 1) | (odd_bits << 1)
📊复杂度分析
|
维度 |
分析 |
|
时间复杂度 |
O(1) (位操作固定) |
|
空间复杂度 |
O(1) (无额外空间) |
🧠示例说明
我们来手动看几个例子:
示例 1:
输入:num = 2
二进制:0000 0010
奇偶位:0b10,位0是0,位1是1 → 交换后变成 0b01 → 输出:1
示例 2:
输入:num = 3
二进制:0000 0011
奇偶位:0b11 → 位0和1都是1,交换后还是 0b11 → 输出:3
示例 3:
输入:num = 6
二进制:0000 0110(位2=1,位1=1,位0=0)
交换后:0000 1001 → 输出:9
🔁进阶思考
这个问题的技巧性在于:
- 利用了掩码提取位;
- 运用了移位代替条件判断;
- 避免了任何循环或分支判断,非常高效!
这类题在嵌入式、图像处理、加密算法中非常常见,尤其适合底层处理和硬件驱动。
📎语言扩展
如果你想在其他语言中实现,方法几乎一样,只需改写语法:
C++ 版本
int exchangeBits(int num) {
int even = num & 0xAAAAAAAA;
int odd = num & 0x55555555;
return (even >> 1) | (odd << 1);
}
Java 版本
public int exchangeBits(int num) {
int even = num & 0xAAAAAAAA;
int odd = num & 0x55555555;
return (even >> 1) | (odd << 1);
}
✅总结
这道题看似简单,实际上蕴含了典型的位运算技巧。掌握这些技巧能大幅提升你处理二进制问题的效率和信心。
🔑 记住这三步:
- 用掩码提取奇偶位;
- 位移完成“交换”;
- 用或运算合并结果。
📘希望这篇文章帮你更好地理解位操作的强大威力。下次再见到类似题目,你就可以秒杀它!
751

被折叠的 条评论
为什么被折叠?



