1. 平衡数问题解析与高效解法
今天我们来聊聊CCF-CSP认证考试中一个有趣的位运算问题——平衡数判断。这个问题看似简单,但其中蕴含着不少值得深入探讨的位运算技巧和优化思路。
1.1 问题定义与基础解法
平衡数的定义非常直观:对于一个正整数,如果其二进制表示中1和0的个数相等,就称为平衡数。这里需要注意几个关键点:
- 二进制表示必须以1开头,不考虑前导零
- 只统计有效位中的0和1数量
- 对于奇数位数的二进制数,不可能成为平衡数(因为1和0的数量必然不等)
最直接的解法就是按照定义来实现:
cpp复制bool isBalanced(int num) {
if(num == 0) return false; // 0没有有效位
int ones = 0, zeros = 0;
while(num > 0) {
if(num & 1) ones++;
else zeros++;
num >>= 1;
}
return ones == zeros;
}
这个实现的时间复杂度是O(k),其中k是num的二进制位数。对于32位整数来说,最多需要32次循环。
1.2 位运算优化思路
虽然基础解法已经足够高效,但我们还可以利用位运算的特性进行优化。观察发现,我们其实不需要分别统计0和1的数量,只需要知道它们的差值是否为0。
改进思路:
- 初始化计数器为0
- 遇到1时加1,遇到0时减1
- 最终检查计数器是否为0
优化后的实现:
cpp复制bool isBalancedOptimized(int num) {
if(num == 0) return false;
int balance = 0;
while(num > 0) {
balance += (num & 1) ? 1 : -1;
num >>= 1;
}
return balance == 0;
}
这个版本减少了变量使用和比较操作,理论上会更高效一些。
1.3 高级位运算技巧
更进一步的优化是利用异或运算的特性。我们可以通过一系列"折叠"操作,将32位整数
