Easy
题目描述
给你一个正整数 n,编写一个函数,返回其二进制表示中数字位数为 ‘1’ 的个数(也被称为汉明重量)。
示例 1:
输入:n = 11
输出:3
解释:输入的二进制串 1011 中,共有 3 位为 '1'。
示例 2:
输入:n = 128
输出:1
解释:输入的二进制串 10000000 中,共有 1 位为 '1'。
示例 3:
输入:n = 2147483645
输出:30
解释:输入的二进制串 1111111111111111111111111111101 中,共有 30 位为 '1'。
提示:
1 <= n <= 2^31 - 1
进阶: 如果多次调用这个函数,你将如何优化你的算法?
解题思路
这道题要求计算一个整数的二进制表示中 1 的个数,有几种常见的解法:
解法一:逐位检查(朴素方法) 通过不断右移和检查最低位来统计 1 的个数。每次检查最低位是否为 1,然后右移一位,直到数字变为 0。
解法二:位运算优化(推荐)
利用 n & (n-1) 的性质,这个操作可以消除 n 的二进制表示中最右边的 1。比如 12(1100)& 11(1011)= 8(1000)。通过不断执行这个操作直到 n 变为 0,操作次数就是 1 的个数。这种方法的优势是循环次数等于 1 的个数,而不是固定的 32 次。
解法三:内置函数
大多数编程语言都提供了内置的位计数函数,如 C++ 的 __builtin_popcount、Python 的 bin(n).count('1')。
解法四:查表法 预先计算所有可能值的汉明重量存储在表中,适合多次调用的场景。
这里采用解法二作为主要实现,因为它既高效又容易理解。
代码实现
class Solution {
public:
int hammingWeight(int n) {
int count = 0;
while (n != 0) {
n &= (n - 1); // 消除最右边的1
count++;
}
return count;
}
};
class Solution:
def hammingWeight(self, n: int) -> int:
count = 0
while n:
n &= n - 1 # 消除最右边的1
count += 1
return count
public class Solution {
public int HammingWeight(int n) {
int count = 0;
while (n != 0) {
n &= (n - 1); // 消除最右边的1
count++;
}
return count;
}
}
var hammingWeight = function(n) {
let count = 0;
while (n !== 0) {
n &= (n - 1); // 消除最右边的1
count++;
}
return count;
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(k) | k 是二进制表示中 1 的个数,最坏情况下 O(log n) |
| 空间复杂度 | O(1) | 只使用常数个变量 |
相关题目
190. Reverse Bits (Easy)
231. Power of Two (Easy)
338. Counting Bits (Easy)
401. Binary Watch (Easy)
461. Hamming Distance (Easy)
762. Prime Number of Set Bits in Binary Representation (Easy)
3280. Convert Date to Binary (Easy)