191. 位1的个数

179 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

每日刷题第73天 2021.03.24

191. 位1的个数

题目描述

  • 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为汉明重量)。

示例

  • 示例1
输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'
  • 示例2
输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'

解题思路

  • 位运算优化解法
  • 观察这个运算:n & (n−1),其运算结果恰为把 n 的二进制位中的最低位的 1 变为 0 之后的结果。
  • 如:6 &(6-1) = 4运算结果 4 即为把 6 的二进制位中的最低位的 1 变为 0 之后的结果。
  • 这样我们可以利用这个位运算的性质加速我们的检查过程,在实际代码中,我们不断让当前的 nn - 1做与运算,直到 n 变为 0 即可。因为每次运算会使得 n 的最低位的 1 被翻转,因此运算次数就等于 n 的二进制位中 1 的个数。

分析

  • 比如10010010,这个数减一是10010001,和10010010与运算之后为10010000,可以发现最右边的1没有了。重复这样的过程,就是1001000010001111与运算,结果为10000000,又消除了一个1。消除1的同时计数器count记录1的个数,当原数值变成0的时候,count的数值就是原数值二进制下1的个数。

AC代码

  • 常规解法
var hammingWeight = function(n) {
  // 按位异或
  let ans = 0;
  while(true) {
    ans += n % 2;
    // 右移就相当于parseInt(n / 2)整除
    n = n >>> 1;
    if(n == 0) break;
  }
  return ans;
};
  • &运算
res += n & 1;
n = n >>> 1;
  • 位运算(找最后一位1)
var hammingWeight = function(n) {
    let ret = 0;
    while (n) {
        n &= n - 1;
        ret++;
    }
    return ret;
};

总结

  • 位运算需要注意,每次取模的时候,记得一定要整除,不然会出现小数的情况,那样就会出错。