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) | 只使用常数个变量 |
相关题目
. Reverse Bits (Easy)
. Power of Two (Easy)
. Counting Bits (Easy)
. Binary Watch (Easy)
. Hamming Distance (Easy)
. Convert Date to Binary (Easy)