LeetCode 338. 比特位计数 (DP、位运算)

比特位计数

  • 暴力,主要使用了lowbit运算。
class Solution {
public:
    vector<int> countBits(int num) {
        vector<int> ans;
        int cnt[32] = {0};
        for(int i=0;i<=num;i++){
            ans.push_back(get1(i));
        }
        return ans;
    }
    int get1(int n){
        int res = 0;
        while(n){
            res++;
            n -= n&(-n);
        }
        return res;
    }
};
  • DP解法,从最低位到最高位,将每一位放置1或0作为DP的阶段。
    比如:

第1阶段
0000 -> 0001
第二阶段
0000 -> 0010
0001 -> 0011
第三阶段
0000 -> 0100
0001 -> 0101
0010 -> 0110
0011 -> 0111

这有点类似用二进制拆分进行倍增的想法,对应的DP的子结构问题。
比如,对于原问题,如果想知道 [ 0 , 15 ] [0,15] [0,15]的情况,要是在已经知道 [ 0 , 7 ] [0,7] [0,7]基础上,
比如 [ a 0 , a 1 , a 2 , a 3 , … … , a 7 ] [a0,a1,a2,a3,……,a7] [a0,a1,a2,a3,a7]那么 [ a 8 , a 9 , a 10 , a 11. … … a 15 ] = [ a 0 + 1 , a 1 + 1 , … … a 7 + 1 ] [a8,a9,a10,a11.……a15]=[a0+1,a1+1,……a7+1] [a8,a9,a10,a11.a15]=[a0+1,a1+1,a7+1]

DP方程:
d p [ i + b ] = d p [ i ] + 1 , b ∈ [ 2 p ] , p = 0 , 1 , 2 , 3 , … … dp[i+b]=dp[i]+1,b\in [2^p],p=0,1,2,3,…… dp[i+b]=dp[i]+1,b[2p],p=0,1,2,3,

class Solution {
public:
    vector<int> countBits(int num) {
        vector<int> dp(num+1,0);
        int p = 0;
        while((1<<p)<=num){
            for(int i=0;i<(1<<p) && i<=num-(1<<p);i++){
                dp[i+(1<<p)] = dp[i]+1;
            }
            p++;
        }
        return dp;
    }
};

或者分析最低位可能更加明显,直接上DP方程:
d p [ x ] = d p [ x / 2 ] + ( x % 2 ) dp[x] = dp[x/2]+(x\%2) dp[x]=dp[x/2]+(x%2)
这样从小到大进行递推,在进行计算x时,x/2就已经算好了。
DP的阶段仍然是二进制下的位数。

class Solution {
public:
    vector<int> countBits(int num) {
        vector<int> ans(num+1,0);
        for(int i=1;i<=num;i++){
            ans[i] = ans[i>>1] + (i&1);
        }
        return ans;
    }
};

你可能感兴趣的:(LeetCode,#,LC位运算,#,LC动态规划)