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)只使用常数个变量

相关题目