题目要求
时间限制:1秒 空间限制:32768K
题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
分析实现
这道题看起来比较简单,直观来看将n直接右移即可,如下:
class Solution {
public:
int NumberOf1(int n) {
int count = 0;
while(n)
{
//这样做可能引起死循环
if(n&1)count++;
n=n>>1;
}
return count;
}
};
然而发现测试过不了,仔细想一下,输入一个负数时,比如0x80000000,右移时符号位也会保留,最后会变成0xFFFFFFFF造成死循环。为避免这种死循环,可以使用左移。
代码如下:
class Solution {
public:
int NumberOf1(int n) {
int count = 0;
unsigned int flag=1;
while(flag)
{
if(n&flag)count++;
flag=flag<<1;
}
return count;
}
};
实际上还有一种更巧妙的做法。一个整数减去1后再和原来的整数做位与运算,得到的结果相当于把整数的二进制的最右边的1变成0。根据这种思路,可以得到代码:
class Solution {
public:
int NumberOf1(int n) {
int count = 0;
while(n)
{
count++;
n=(n-1)&n;
}
return count;
}
};