LeetCode-位1的个数-题号191-Java实现
1、题目链接
2、题目大意
给你一个整数,求该整数的二进制写法中有多少位是1
3、样例输入
4294967293
4、样例输出
31
5、思路
将十进制数转化为二进制数的方法大家一定写过,代码如下:
public class Solution { // you need to treat n as an unsigned value public int hammingWeight(int n) { int cnt = 0; while (n != 0) { cnt += (n % 2); n /= 2; } return cnt; } }
很遗憾,这份代码过不了这个题,因为题目给的数是无符号整数,而Java没有无符号整数,也就是意味着同样一个二进制数,比如11111111111111111111111111111101,这个数如果是无符号整数,那么十进制写法就是4294967293,如果是有符号数,那么十进制写法就是-3,这就导致了直接对数n进行取余运算会计算出负数,从而导致结果错误。
因此,我们要使用位运算,直接对二进制数进行判断,代码如下:
public class Solution { // you need to treat n as an unsigned value public int hammingWeight(int n) { int cnt = 0; for (int i = 0; i < 32; i++) { if ((n & (1 << i)) != 0) { cnt++; } } return cnt; } }
题目输入最多只有32位,所以只需要循环32次,通过将1向左位移,并且将位移后的数与n做与运算,判断结果是否为0即可确认当前位是否为1,有想法的小伙伴可以把这个循环再优化优化,比如 1<<i 这一步,实际上不需要每次循环都位移i位。
到这里这个题就结束了,不过我提交完后看了眼题解,发现评论区有个小伙伴直接调了Integer.bitCount(n)方法,于是我点进去看了bitCount的源码(见第六节代码部分),有兴趣的小伙伴可以看看这篇。
6、代码
public class Solution { // you need to treat n as an unsigned value public int hammingWeight(int n) { n = n - ((n >>> 1) & 0x55555555); n = (n & 0x33333333) + ((n >>> 2) & 0x33333333); n = (n + (n >>> 4)) & 0x0f0f0f0f; n = n + (n >>> 8); n = n + (n >>> 16); return n & 0x3f; } }
上一篇:
IDEA上Java项目控制台中文乱码