338.比特位计数

  • 338.比特位计数
  • 题目:
    输入一个num,输出一个长度为n+1的数组,元素分别为[ 0,num ]对应的二进制数的1的个数;
  • 思路:
    1.暴力:时间O(32n),空间O(1)
    遍历[ 0,num ],分别计算每个数的二进制的1的个数;
class Solution {
    
    
public:
    vector<int> countBits(int num) {
    
    
        vector<int> res(num + 1);
        for (int i = 0; i <= num; ++i) {
    
    
            int count = 0;
            int j = i;
            while (j) {
    
    
                ++count;
                j &= (j - 1);//只找二进制为1的地方,不用逐位判断
            }
            res[i] = count;
        }

        return res;
    }
};

2.最低有效位dp:O(n),O(1)

class Solution {
    
    
public:
    vector<int> countBits(int num) {
    
    
        vector<int> res(num + 1);
        for (int i = 0; i <= num; ++i) {
    
    //i>>1还是0,即i取0时,下面dp递推式结果正确,因此可以从0开始
            res[i] = res[i >> 1] + (i & 1);//偶数右移不变,奇数右移少一个;(i>>1) < i
        }

        return res;
    }
};

3.最低设置位dp:O(n),O(1)

class Solution {
    
    
public:
    vector<int> countBits(int num) {
    
    
        vector<int> dp(num + 1);
        for (int i = 1; i <= num; ++i) {
    
    //注意,下面用到了i-1,因此i不能从0开始
            dp[i] = dp[i & (i - 1)] + 1;//i&(i-1) < i
        }

        return dp;
    }
};

4.最高有效位dp:O(n),O(1)

class Solution {
    
    
public:
    vector<int> countBits(int num) {
    
    
        vector<int> dp(num + 1);
        int highBit = 1;//初始化为1,是因为下面循环从1开始,此时的最高有效位的权重是1
        for (int i = 1; i <= num; ++i) {
    
    
            if ((i & (i - 1)) == 0) highBit = i;//每当i成为2的整数幂,此时二进制1的个数只有1个,在i成为下一个2的整数幂之前,最高有效位的权重始终是highBit
            dp[i] = dp[i - highBit] + 1;//例如(5)10=(101)2, 去掉最高有效位的权重,即100对应的4之后,剩下的部分在之前都算过了(i-highBit < i)
        }

        return dp;
    }
};

猜你喜欢

转载自blog.csdn.net/jiuri1005/article/details/114303259
今日推荐