题目描述
给定一个 int型的数字,求它的二进制表示有多少个1.
题解
涉及到了二进制,就应该使用位运算了。
x & (x-1)
可以消除最低位的二进制位1
代码:
public class Solution {
public int NumberOf1(int n) {
int count = 0;
while(n != 0){
// 去除最低位的 1
n = (n&(n-1));
count++;
}
return count;
}
}
错误典型
以下一些方式是错误的:
- 认为有特殊情况,int值为Integer.MIN_VALUE,决定使用long类型来承接int值
Integer.MIN_VALUE在两种类型中的表现形式是不一样的public class Solution { public int NumberOf1(int n) { long b = n; int count = 0; // 去除最低位的 1 while(b != 0){ b = (b&(b-1)); count++; } return count; } }
int型:10000000000000000000000000000000 long型:1111111111111111111111111111111110000000000000000000000000000000
- 使用位运算移位的方式,让字符串右移动
这里属于不熟悉位运算的移位操作,public class Solution { // you need to treat n as an unsigned value public int hammingWeight(int n) { int count = 0; while(n != 0){ if((n & 1) == 1) count++; // 这里使用符号错了 n = n >> 1; } return count; } }
>>
表示的移位,我们一般的理解是类似于/2
操作。这种移位是保留符号的,我们以为的Integer.MIN_VALUE>
移位:
实际上的Integer.MIN_VALUE10000000000000000000000000000000 1000000000000000000000000000000 100000000000000000000000000000 10000000000000000000000000000 1000000000000000000000000000 100000000000000000000000000 10000000000000000000000000 1000000000000000000000000 100000000000000000000000 10000000000000000000000 1000000000000000000000 100000000000000000000 10000000000000000000 1000000000000000000 100000000000000000 10000000000000000 1000000000000000 100000000000000 10000000000000 1000000000000 100000000000 10000000000 1000000000 100000000 10000000 1000000 100000 10000 1000 100 10 1
>>
移位:
明确一点:10000000000000000000000000000000 11000000000000000000000000000000 11100000000000000000000000000000 11110000000000000000000000000000 11111000000000000000000000000000 11111100000000000000000000000000 11111110000000000000000000000000 11111111000000000000000000000000 11111111100000000000000000000000 11111111110000000000000000000000 11111111111000000000000000000000 11111111111100000000000000000000 11111111111110000000000000000000 11111111111111000000000000000000 11111111111111100000000000000000 11111111111111110000000000000000 11111111111111111000000000000000 11111111111111111100000000000000 11111111111111111110000000000000 11111111111111111111000000000000 11111111111111111111100000000000 11111111111111111111110000000000 11111111111111111111111000000000 11111111111111111111111100000000 11111111111111111111111110000000 11111111111111111111111111000000 11111111111111111111111111100000 11111111111111111111111111110000 11111111111111111111111111111000 11111111111111111111111111111100 11111111111111111111111111111110 11111111111111111111111111111111 11111111111111111111111111111111 11111111111111111111111111111111 ... 陷入死循环
>>
是有符号右移,相等于/2
,负数的那最高位1
是不会移动的>>>
是无符号位移,是可以将最高位的1
移动的
public class Solution { // you need to treat n as an unsigned value public int hammingWeight(int n) { int count = 0; while(n != 0){ if((n & 1) == 1) count++; n = n >>> 1; } return count; } }