• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • YouClaw
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

youyou-dev

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

位运算计算整数二进制中 1 的个数

位运算

目录
  • 位运算
    • 1. 常用技巧与应用
      • (1)判断奇偶
      • (2)交换两数(不用临时变量)
      • (3)计算二进制中 1 的个数(汉明重量)
      • (4)判断 2 的幂
      • (5)取低 n 位
      • (6)将某位置 1
      • (7)将某位置 0
      • (8)取反(相当于异或 1)
    • 3. 为什么需要位运算?
    • 4. 与之前问题的关联
    • 5. 注意事项
    • 力扣真题
  • null

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

image

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 的个数

image

解法一:

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 被清除了。

算法步骤

  1. 初始化计数器 count = 0。
  2. 当 n != 0 时:
    • n = n & (n-1)(清除最低位的 1)
    • count++
  3. 返回 count。
class Solution {
    public int hammingWeight2(int n) {
        int count = 0;
        while (n != 0) {
            n &= (n - 1);
            count++;
        }
        return count;
    }
}

posted on 2026-03-28 19:37  U~U  阅读(5)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3