题目
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为'1'
的个数(也被称为 汉明重量))。
示例 1:
输入:n = 11 (控制台输入 00000000000000000000000000001011) 输出:3 解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 ‘1’。
示例 2:
输入:n = 128 (控制台输入 00000000000000000000000010000000) 输出:1 解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 ‘1’。
示例 3:
输入:n = 4294967293 (控制台输入 11111111111111111111111111111101,部分语言中 n = -3) 输出:31 解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 ‘1’。
解题思路:逐位判断
我们可以直接循环检查给定整数 的二进制位的每一位是否为
。
复杂度分析
时间复杂度:,其中
为
型的二进制位数,
。我们需要逐位检查二进制共
位
空间复杂度:,我们只需要常数的空间保存若干变量。
🚩官方代码
public int hammingWeight(int n) {
int cnt = 0;
while (n != 0) {
cnt += n & 1;
n >>>= 1; // 无符号位右移
}
return cnt;
}
解题思路:位运算优化
观察运算:,其预算结果恰为把
的二进制位中的最低位的
1
变为 0
之后的结果。
如下面的例子: ,运算结果
4
即为把 6
的二进制位中的最低位的 1
变为 0
之后的结果。
这样我们可以利用这个位运算的性质加速我们的检查过程,在实际代码中,我们不断让当前的 与
做与运算,直到
变为
即可。因为每次运算会使得
的最低位的
被翻转,因此运算次数就等于
的二进制位中
的个数。
复杂度分析
时间复杂度:,循环次数等于
的二进制位中
的个数,最坏情况下
的二进制位全部为
空间复杂度:,我们只需要常数的空间保存若干变量。
🚩官方代码
public class Solution {
public int hammingWeight(int n) {
int ret = 0;
while (n != 0) {
n &= n - 1;
ret++;
}
return ret;
}
}