10.Number of 1 Bits

来源:互联网 发布:史崔克装甲车数据 编辑:程序博客网 时间:2024/06/08 15:39

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)。

0 0
原创粉丝点击