mirror of
https://github.com/krahets/LeetCode-Book.git
synced 2026-01-12 00:19:02 +08:00
5.1 KiB
Executable File
5.1 KiB
Executable File
方法一:逐位判断
根据 与运算 定义,设二进制数字 n ,则有:
- 若
n \& 1 = 0,则n二进制 最右一位 为0; - 若
n \& 1 = 1,则n二进制 最右一位 为1。
根据以上特点,考虑以下 循环判断 :
- 判断
n最右一位是否为1,根据结果计数。 - 将
n右移一位(本题要求把数字n看作无符号数,因此使用 无符号右移 操作)。
算法流程:
- 初始化数量统计变量
res = 0。 - 循环逐位判断: 当
n = 0时跳出。res += n & 1: 若n \& 1 = 1,则统计数res加一。n >>= 1: 将二进制数字n无符号右移一位( Java 中无符号右移为 "$>>>$" ) 。
- 返回统计数量
res。
代码:
class Solution:
def hammingWeight(self, n: int) -> int:
res = 0
while n:
res += n & 1
n >>= 1
return res
public class Solution {
public int hammingWeight(int n) {
int res = 0;
while(n != 0) {
res += n & 1;
n >>>= 1;
}
return res;
}
}
class Solution {
public:
int hammingWeight(uint32_t n) {
unsigned int res = 0; // c++ 使用无符号数
while(n != 0) {
res += n & 1;
n >>= 1;
}
return res;
}
};
复杂度分析:
- 时间复杂度
O(\log_2 n): 此算法循环内部仅有 移位、与、加 等基本运算,占用O(1);逐位判断需循环log_2 n次,其中\log_2 n代表数字n最高位1的所在位数(例如\log_2 4 = 2, $\log_2 16 = 4$)。 - 空间复杂度
O(1): 变量res使用常数大小额外空间。
方法二:巧用 n \& (n - 1)
(n - 1)解析: 二进制数字n最右边的1变成0,此1右边的0都变成1。n \& (n - 1)解析: 二进制数字n最右边的1变成0,其余不变。
算法流程:
- 初始化数量统计变量
res。 - 循环消去最右边的
1:当n = 0时跳出。res += 1: 统计变量加1;n &= n - 1: 消去数字n最右边的1。
- 返回统计数量
res。
代码:
class Solution:
def hammingWeight(self, n: int) -> int:
res = 0
while n:
res += 1
n &= n - 1
return res
public class Solution {
public int hammingWeight(int n) {
int res = 0;
while(n != 0) {
res++;
n &= n - 1;
}
return res;
}
}
class Solution {
public:
int hammingWeight(uint32_t n) {
int res = 0;
while(n != 0) {
res++;
n &= n - 1;
}
return res;
}
};
复杂度分析:
- 时间复杂度
O(M):n \& (n - 1)操作仅有减法和与运算,占用O(1);设M为二进制数字n中1的个数,则需循环M次(每轮消去一个1),占用O(M)。 - 空间复杂度
O(1): 变量res使用常数大小额外空间。













