您的位置:首页 > 其它

10.Number of 1 Bits

2015-10-16 10:38 127 查看
Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also known as the Hamming
weight).

For example, the 32-bit integer ’11' has binary representation
00000000000000000000000000001011
,
so the function should return 3.

Credits:

Special thanks to @ts for adding this problem and creating all test cases.

分析:给定int型整数n,判断n的二进制形式中1的个数。

在分析的时候总共有2种实现方法。

方法一:n转化成二进制字符串,然后遍历字符串中字符为1的个数。在leetcode上提交通过。但是效率不高。

/*提交通过*/
public int hammingWeight1(int n) {
String binary = Integer.toBinaryString(n);
int result=0;
for(int i=0;i<binary.length();i++){
char ch=binary.charAt(i);
if(ch=='1'){
result++;
}

}
return result;
}


方法二:

step1:判断n是否为0;为0则结束,否则转step2;

step2:n与1进行位与操作,如果结果为1则c++;

Step3:n>>>=1(n逻辑右移一位)

/*提交通过*/
public int hammingWeight2(int n) {
int c=0;
while(n!=0)
{
if((n&1)==1)
c++;
n>>>=1;//注意这个地方要用n>>>=1逻辑右移,不可以用n>>=1的算数右移(如果用了算数右移,可能会进入死循环,当输入是负数的时候)
}
return c;
}


方法三:

/*
* n&(n-1)的结果是把n最右边的1变成0,这样循环的次数就是n中1的个数
*/
public int hammingWeight3(int n) {
int count = 0;
while (n!=0) {
count++;
n = (n-1)&n;//1101&1100=1100
}
return count;
}


方法四:针对方法二进行改变,不让n右移,相反的选择一个标志位flag=1让其逐步左移,统计1的个数。

public int hammingWeight4(int n) {
int count = 0;
int flag = 1;
while (flag!=0) {  //整个循环的次数等于整数二进制的位数
if((n&flag)!=0){
count++;
}
flag = flag << 1;//每次让flag左移一位。
}
return count;
}


需要明白java对数的右移运算。java分为逻辑右移和算术右移。因为题目的给的是无符号数,并且是要计算其中1的个数,所以用到的是逻辑右移。

比如一个有符号位的8位二进制数11001101,逻辑右移就不管符号位,如果移一位就变成01100110。算术右移要管符号位,右移一位变成10100110。
逻辑左移=算数左移,右边统一添0
逻辑右移,左边统一添0
算数右移,左边添加的数和符号有关,如果是正数则左边添加的全是0,否则添加的全是1.
e.g:1010101010,其中[]位是添加的数字
逻辑左移一位:010101010[0]
算数左移一位:010101010[0]
逻辑右移一位:[0]101010101
算数右移一位:[1]101010101
在看《剑指offer》这本书的时候发现了后两种更好的解法。

上面的四种方法综合比较得知最好的是第三种方法利用n&(n-1)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: