【LeetCode-位运算】位1的个数
题目描述
编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。
示例:
输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。
输入:11111111111111111111111111111101
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。
题目描述: https://leetcode-cn.com/problems/number-of-1-bits/
思路1
因为输入的是无符号数字,所以如果数字的最高位为 1,右移的话高位也会补 0。所以可以用左移来做,代码如下:
class Solution {
public:
int hammingWeight(uint32_t n) {
int cnt = 0;
while(n!=0){
if(n&1==1) cnt++;
n>>=1;
}
return cnt;
}
};
注意,如果输入的 n 是有符号数,就不能这样做了。因为,如果 n 是负数,那么右移高位会补 1。
- 时间复杂度:O(logn)
- 空间复杂度:O(1)
思路2
我们设置一个掩码 mask = 1,每次将 mask 左移一位,移动 32 次,每次移动都和 n 做与操作,如果结果为 1,说明 n 的当前位为 1。代码如下:
class Solution {
public:
int hammingWeight(uint32_t n) {
int cnt = 0;
unsigned int mask = 1;
for(int i=0; i<32; i++){
if(mask&n) cnt++; // 注意,不要写成 if(mask&n==1),也不要写成 if(mask&n!=0)
mask = mask<<1;
}
return cnt;
}
};
如果 n 是有符号整数,这种方法也能得到正确的答案,而思路 1 会发生错误。
- 时间复杂度:O(1)
- 空间复杂度:O(1)
思路3
将 n 和 n-1 做与运算,会使得 n 的最低位的1变为 0. 例如,n = 3 = 11,n-1 = 2 = 10, n&(n-1) = 11&10 = 10. 所以,假设 n 和 n-1 做与运算 cnt 次后,n 变为 0,则 说明 n 中有 cnt 个 1.代码如下:
class Solution {
public:
int hammingWeight(uint32_t n) {
int cnt = 0;
while(n){
cnt++;
n = n&(n-1);
}
return cnt;
}
};