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;
    }
}
经验分享 程序员 微信小程序 职场和发展