天天看点

剑指offer 15. 二进制中1的个数剑指offer 15. 二进制中1的个数

剑指offer 15. 二进制中1的个数

题目描述

剑指offer 15. 二进制中1的个数剑指offer 15. 二进制中1的个数

解题思路

循环和位移动

用掩码检查整数的每一位,并不断将掩码左移。

循环的次数等于整数的二进制的位数,32位的整数需要循环32次。

public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int bits = 0;  //二进制 1 的个数
        int mask = 1;  //用掩码检查每一位是否为1

        for (int i = 0; i < 32; i++) {
            if ((n & mask) != 0) {
                bits++;
            }
            mask <<= 1;   //右移一位
        }
        return bits;
    }
}
           

位操作的小技巧

这种解法能够实现整数的二进制中有几个1就只需要循环几次。

如果一个整数不为0,那么这个整数的二进制至少有一个1。如果把这个整数减去1,则原来最右边的1会变成0,原来在这个1的右边所有的0全部变成1,其余的所有位全不受影响。例如,1100减去1变成1011。

利用上述规则,如果n和n-1做与运算,将会把n最右边的1消去,其余位不受影响,例如,1100 & 1011 = 1000。那么,n中有多少个1就会进行多少次这样的操作。

public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int bits = 0;  //二进制 1 的个数

        while (n != 0) {
            bits++;
            n &= (n - 1);
        }
        return bits;
    }
}