题目描述:
给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。
示例
示例 1:
输入: 2
输出: [0,1,1]
示例 2:
输入: 5
输出: [0,1,1,2,1,2]
解答:
class Solution {
public:
vector<int> countBits(int num) {
vector<int>dp;
dp.push_back(0);
if(num==0)
return dp;
if(num==1){
dp.push_back(1);
return dp;
}
else if (num==2){
dp.push_back(1);
dp.push_back(1);
return dp;
}
else{
int p = 1;
int offset = 2;
dp.push_back(1);
dp.push_back(1);
for (int i = 3; i <= num; i++)
if (i > pow(2, p)&&i<pow(2,p+1))
dp.push_back(dp[i - offset] + 1);
else {
dp.push_back(1);
p++;
offset = pow(2, p);
}
return dp;
}
}
};
对于边界的几个数字,直接偷懒手动解决掉了。
对于任意数字i,
如果是2的乘方数,则dp[i]=1,
如果不是2的乘方数,则肯定夹在pow(2,p)和pow(2,p+1)之间,当i减掉pow(2,p)时,在二进制的角度看,相当于拿掉最高位的1,则转变为了dp[i-pow(2,p)]的情况,故有转移方程dp[i]=dp[i - pow(2,p)] + 1。