15-二进制中1的个数
大约 1 分钟
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
第一种 无符号右移
用1去和n做与运算,然后检查最低位是否是1,然后将n做无符号右移操作。有符号的右移是>>,无符号的右移是>>>。这两者的区别主要在于对负数的移位操作,前者对负数右移会在最高位补1,后者不会。所以右移操作需要使用无符号的右移,如果使用有符号的右移,当为负数时,会出现无限循环的问题。
public int NumberOf1(int n) {
int count = 0;
while (n != 0) {
if( (n & 1) == 1){ //如果最后一位是1,那么就计数
count++;
}
n = n >>> 1;
}
return count;
}
第二种 左移
我们可以将第一种方法反过来,n不动,让1不断的向左移位,与n做与运算。java中int是32位,所以循环次数为32次。
public int NumberOf1(int n) {
int flag = 1;
int count = 0;
while (flag != 0) {
if( (n & flag) != 0 ){
count++;
}
flag = flag << 1;
}
return count;
}
第三种 与运算技巧
先来看一个运算。 10 = 1010 10 - 1= 9=1001 1010 & 1001 = 1000 可以得到一个结论,数字n与数字n-1做与运算,会将n最右边的1变为0。即n中有多少个1,就可以进行多少次这样的计算。
public int NumberOf1(int n) {
int count = 0;
while (n != 0) {
count++;
n = (n - 1) & n;
}
return count;
}