位运算计算整数二进制中 1 的个数
位运算
目录
位运算(Bitwise Operation)是对整数的二进制位进行直接操作的运算方式。在计算机底层,数据都以二进制形式存储,位运算效率极高,常用于性能敏感、权限控制、状态压缩等场景。


1. 常用技巧与应用
(1)判断奇偶
if ((n & 1) == 1) // 奇数
if ((n & 1) == 0) // 偶数
(2)交换两数(不用临时变量)
a ^= b;
b ^= a;
a ^= b;
(3)计算二进制中 1 的个数(汉明重量)
int count = 0;
while (n != 0) {
n &= (n - 1); // 消去最低位的 1
count++;
}
(4)判断 2 的幂
boolean isPowerOfTwo = (n > 0) && ((n & (n - 1)) == 0);
(5)取低 n 位
int lowBits = value & ((1 << n) - 1);
(6)将某位置 1
value |= (1 << pos);
(7)将某位置 0
value &= ~(1 << pos);
(8)取反(相当于异或 1)
value ^= (1 << pos); // 翻转某一位
3. 为什么需要位运算?
- 效率高:直接操作寄存器,比乘除、取模快很多。
- 节省空间:可以用一个整数的不同位表示多个布尔状态(如 Linux 文件权限
rwx)。 - 底层控制:网络协议、加密算法、硬件驱动等常依赖位运算。
4. 与之前问题的关联
位运算解法:
while (n != 0) {
n &= (n - 1);
count++;
}
利用了 n & (n-1) 每次清除最低位的 1,循环次数就是 1 的个数,比逐位检查或字符串转换更高效。
“十进制整数的反码”也可以直接用异或实现:
int mask = (Integer.highestOneBit(n) << 1) - 1;
return n ^ mask;
5. 注意事项
- 对
int和long进行移位时,实际移位的位数是 对模 32(或 64)取余,如1 << 35相当于1 << 3。 - 负数的右移
>>会保留符号位,无符号右移>>>则始终补 0。 - 按位取反
~得到的是补码形式的结果,直接打印可能不是预期值(如~5输出 -6)。
力扣真题
位运算计算整数二进制中 1 的个数

解法一:
class Solution {
public int hammingWeight(int n) {
int num = 0;
String binary = Integer.toBinaryString(n);
for (int i = 0; i < binary.length(); i++) {
if(binary.charAt(i)=='1'){
num++;
}
}
return num;
}
}
解法二:(最优解)
对于任意整数 n,表达式 n & (n-1) 的结果等于将 n 的二进制表示中最右边的 1 变成 0 后的数。
为什么?
n-1会将n的最低位的 1 变为 0,且该位右边的所有位都变为 1。- 例如
n = 12(二进制1100),n-1 = 11(二进制1011)。 1100 & 1011 = 1000,最低位的 1 被清除了。
算法步骤
- 初始化计数器
count = 0。 - 当
n != 0时:n = n & (n-1)(清除最低位的 1)count++
- 返回
count。
class Solution {
public int hammingWeight2(int n) {
int count = 0;
while (n != 0) {
n &= (n - 1);
count++;
}
return count;
}
}
浙公网安备 33010602011771号