191.Number of 1Bits---位运算---《剑指offer》10
题目链接:https://leetcode.com/problems/number-of-1-bits/description/
题目大意:与338题类似,求解某个无符号32位整数的二进制表示的1的个数。注意要求是无符号32位整数。
注意:无符号整数的范围是0~2^32-1,而普通int的范围是-2^31 ~ 2^31-1。
法一:直接用普通十进制转二进制的办法做,发现超时了,超时数据是2^31,当我把这个数放进eclipse中发现直接报错,至于为什么在leetcode里还可以编译通过,我也不知道。想看它的测试代码,发现并没有公开。代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public int hammingWeight(int n) { 2 int cnt = 0; 3 while(n != 0) { 4 cnt += n & 1; 5 n >>= 1; 6 } 7 return cnt; 8 }
生气!这段代码用C++提交,AC了!耗时3ms,生气!😠
法二(借鉴):用Integer自带的转为无符号二进制的类库做,ac了,蒙蔽。代码如下(耗时3ms):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public int hammingWeight(int n) { 2 int cnt = 0; 3 String s = Integer.toBinaryString(n);//转为无符号二进制 4 char[] binaries = s.toCharArray(); 5 for(char c : binaries) { 6 if(c == '1') { 7 cnt++; 8 } 9 } 10 return cnt; 11 }
法三(借鉴):编程之美P121解法3,只计数1的个数,将复杂度降为只与1的个数有关。位运算很巧妙。代码如下(耗时2ms):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public int hammingWeight(int n) { 2 int cnt = 0; 3 while(n != 0) { 4 //1001 5 //1001-1=1000 1001&1000=1000 6 //1000-1=0111 1000&0111=0 7 //1的个数是2,所以会计算两次 8 n &= (n - 1); 9 cnt++; 10 } 11 return cnt; 12 }
法四(借鉴):只用循环32次,也就是用位运算n&(1<<i),取出数值n的每一位二进制的值,查看是否非0。代码如下(耗时2ms):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public int hammingWeight(int n) { 2 int cnt = 0; 3 for(int i = 0; i <= 31; i++) { 4 //1<<i表示1左移i位,n&(1<<i)表示取n的第i位数值 5 if((n & (1<<i)) != 0) { 6 cnt++; 7 } 8 } 9 return cnt; 10 }
还有一些打表的算法,在这个博客里面:http://www.cnblogs.com/stoneJin/archive/2011/10/26/2224900.html