题目
输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。
示例1
输入
10
返回值
2
解1 位移动
由于负数符号位为1,对于数字的右移,补位为符号位,因此判断时,我们先将n的符号位转0,转成一个整数temp,然后判断temp的1位数有几位。
判断方法:
- 设置一个计数变量
- 通过循环,循环条件为temp不为0。
- 每次将temp&1,获取最后一位的值。如果是1,nCount+1;否则不加
- temp右移一位。
当temp为0,即没有1了。此时再判断n的大小,小于0则nCount+1,加上符号位的1;否则不加。nCount即1的位数
class Solution {
public:
int NumberOf1(int n) {
int temp = n&(INT_MAX);
int nCount = 0;
while (temp!=0)
{
if((temp&1) == 1)
nCount++;
temp >>= 1;
}
if(n < 0) nCount++;
return nCount;
}
};
解2
列举:
数字 | 二进制 |
---|---|
11 | 0000 1011 |
12 | 0000 1100 |
13 | 0000 1101 |
14 | 0000 1110 |
15 | 0000 1111 |
我们对比每一个n,每次n-1的二进制数即把n最右边的1到后面全部取反,也就说明把最右边的1消除。
例如:n = 14:1110;n=13:1101
14最后一位1是第2位,13则是把14最后两位取反
n = 13:1101;n=12:1100
13最后一位1是第1位,12则是把13最后一位取反
我们可以借助该规律,每和n-1相与一次,则消除了一个1,nCount便加1:
class Solution {
public:
int NumberOf1(int n) {
int nCount = 0;
while(n != 0)
{
nCount++;
n = n&(n-1);
}
return nCount;
}
};