题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
解题思路
- 一开始看到题目说负数用补码表示,以为是让我用补码表示输入的十进制负数再count,没想到意思是输入的就是补码表示的负数(我一直默认输入十进制,其实也可以二进制等TAT)。但是虽然是负数的补码右移会在最高位补1,因此会陷入死循环。。所以我一开始做题还是将输入的负数转为正数再计算1的个数,但是需要注意int的范围是
-2^31~2^31-1
,负数比正数多表示一位,即-2^31
没有对应的正数,需要特判。。关于负数中的1的计算公式=32-正数数位长+count(第一个1之后的0的个数)+1
Code
class Solution {
public:
int NumberOf1(int n) {
if(n == (-1<<31)) {
return 1;
}
int res = 0;
if(n < 0) {
n = -n;
int digitLength = 0, countZeros = 0, hasOne = 0;
while(n) {
digitLength ++;
if(n & 1) {
if(!hasOne) {
hasOne = 1;
}
} else {
if(hasOne) {
countZeros ++;
}
}
n = n >> 1;
}
res = 32-digitLength+countZeros+1;
} else {
while(n) {
res += n & 1;
n = n >> 1;
}
}
return res;
}
};
- java
public class Solution {
public int NumberOf1(int n) {
int result = 0, tem = 1;
for(int i = 0; i<32; i++) {
if((n&tem) == tem) {
result++;
}
tem <<= 1;
}
return result;
}
}
总结
用n&(n-1)
可以移除n在二进制中最右边的那个1