输入一个整数 n ,输出该数32位二进制表示中1的个数。其中负数用补码表示。
数据范围:- 231<= n <= 231-1
即范围为:-2147483648<= n <= 2147483647
示例1输入: 10 返回值: 2 说明: 十进制中10的32位二进制表示为0000 0000 0000 0000 0000 0000 0000 1010,其中有两个1。示例2
输入: -1 返回值: 32 说明: 负数使用补码表示 ,-1的32位二进制表示为1111 1111 1111 1111 1111 1111 1111 1111,其中32个1思路/解法
方式一负数一般用补码表示,补码 = 原码取反 + 1,其中二进制中的最高位表示符号位,最高位是1表示负数,最高位是0表示整数。
当数为负数时,找寻其中规律,由于负数本身使用补码表示,对其位运算(~)取反得到的数求其中二进制中包含几个1,最后使用32减去取反的数包含的1,即可得到该负数二进制中包含1的个数。
class Solution {
public:
int NumberOf1(int n) {
bool flag = false;
if(n < 0)
{
n = (~n);
flag = true;
}
int res = 0;
while(n!=0)
{
if(n % 2 == 1)
res++;
n /=2;
}
if(flag)
res = 32 - res;
return res;
}
};
方式二
位运算符右移。
class Solution {
public:
int NumberOf1(int n) {
int res = 0;
for(int i = 0;i<32;i++)
{
if((n & 1) != 0)res++;
n = n>>1;
}
return res;
}
};
方式三
n&(n - 1),其预算结果恰为把 n 的二进制位中的最低位的 1 变为 0之后的结果
算法流程:
初始化数量统计变量 res
循环消去最右边的 1 :当 n = 0时跳出。
res += 1 : 统计变量加 1 ;
n &= n - 1 : 消去数字 n 最右边的 1 。
返回统计数量 res。
class Solution {
public:
int NumberOf1(int n) {
int res = 0;
while(n!=0)
{
res++;
n = n&(n-1);
}
return res;
}
};



