【LeetCode-位运算】位1的个数

题目描述

编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。
示例:

输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

输入:11111111111111111111111111111101
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。

题目描述: https://leetcode-cn.com/problems/number-of-1-bits/

思路1

因为输入的是无符号数字,所以如果数字的最高位为 1,右移的话高位也会补 0。所以可以用左移来做,代码如下:

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int cnt = 0;
        while(n!=0){
            if(n&1==1) cnt++;
            n>>=1;
        }
        return cnt;
    }
};

注意,如果输入的 n 是有符号数,就不能这样做了。因为,如果 n 是负数,那么右移高位会补 1。

  • 时间复杂度:O(logn)
  • 空间复杂度:O(1)

思路2

我们设置一个掩码 mask = 1,每次将 mask 左移一位,移动 32 次,每次移动都和 n 做与操作,如果结果为 1,说明 n 的当前位为 1。代码如下:

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int cnt = 0;
        unsigned int mask = 1;
        for(int i=0; i<32; i++){
            if(mask&n) cnt++;  // 注意,不要写成 if(mask&n==1),也不要写成 if(mask&n!=0)
            mask = mask<<1;
        }
        return cnt;
    }
};

如果 n 是有符号整数,这种方法也能得到正确的答案,而思路 1 会发生错误。

  • 时间复杂度:O(1)
  • 空间复杂度:O(1)

思路3

将 n 和 n-1 做与运算,会使得 n 的最低位的1变为 0. 例如,n = 3 = 11,n-1 = 2 = 10, n&(n-1) = 11&10 = 10. 所以,假设 n 和 n-1 做与运算 cnt 次后,n 变为 0,则 说明 n 中有 cnt 个 1.代码如下:

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int cnt = 0;
        while(n){
            cnt++;
            n = n&(n-1);
        }
        return cnt;
    }
};
posted @ 2020-07-11 11:29  Flix  阅读(176)  评论(0编辑  收藏  举报