题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
时间限制:1秒 空间限制:32768K 热度指数:243756
解答1:解答2更优
思路:n的二进制的最右边位与1相与,如果是1,则加1;然后对1进行左移,成为二进制的10,继续与n的二进制右边数起的第二位进行相与。。。,32位的整数就循环32次
public class Solution {//负数用补码表示,最高位为1
public int NumberOf1(int n) {
if (n == 0) {
return 0;
}
int count = 0;
int flag = 1;
while (flag != 0) {//这里为什么是flag!=0呢,是因为flag一直向左移,当到1000 0000 0000 0000时,如果再左移,就回到了0
if ((n&flag) != 0) {//这里为什么是!=0呢,是因为n有可能是负数,当两个相与的时候,结果小于0
count++;
}
flag = flag << 1;
}
return count;
}
}
解答2:
public class Solution {//负数用补码表示,最高位为1
public int NumberOf1(int n) {
if (n == 0) {
return 0;
}
int count = 0;
while (n != 0) {//当n不为0时,其他任意整数的二进制至少有一个1
n = n & (n-1);//n-1,如果n的二进制右边数第一位是1,则变为0,如果到某几位才为1时,如:0110 0100,则最右边的1变为0,
//原先1的右边的00都变为1:0110 0011,然后与n相与;得到的值正好是:0110 0000: -》 只会将最右边的1变为0
count++;
}
return count;
}
}