题目
输入一个32位整数,输出该数二进制表示中1的个数。
注意:
负数在计算机中用其绝对值的补码来表示。
样例1
输入:9
输出:2
解释:9的二进制表示是1001,一共有2个1。
样例2
输入:-2
输出:31
解释:-2在计算机里会被表示成11111111111111111111111111111110,一共有31个1。
解法1:位运算循环
难点在于如何处理负数
C++中右移一个负数,会在最高位补上符号位,这样负数就会不停补上1,因此我们可以先将其转换成无符号整数,这样右移最高位补0
时间复杂度O(logn),空间复杂度O(1)
class Solution {
public:
int NumberOf1(int n) {
int ans = 0;
unsigned int a = n;
while (a) {
ans += a & 1;
a >>= 1;
}
return ans;
}
};
解法二:位运算特殊操作
n & (n - 1)可以把n中最右边的1变成0,其余位保持不变
这样时间复杂度就降至O(k),k是n中1的个数,空间复杂度O(1)
class Solution {
public:
int NumberOf1(int n) {
int ans = 0;
while (n) {
ans++;
n = n & (n - 1);
}
return ans;
}
};