比特位计数
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;
}
};
第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;
}
};