题目链接:点击查看
题目描述:
给定一个非负整数
n
,求从
0
到
n
的所有数字的二进制表达中,分别有多少个
1
。
输入输出:
输入: 2 输出: [0,1,1]输入: 5 输出: [0,1,1,2,1,2]
题目分析:
本题可以利用动态规划和位运算进行快速的求解。定义一个数组
dp
,其中
dp[i]
表示数字
i 的二进制含有 1
的个数。对于第
i
个数字,如果它二进制的最后一位为
1
,那么它含有
1
的个数则为 dp[i-1] + 1
;如果它二进制的最后一位为
0
,那么它含有
1
的个数和其算术右移结果相同,即dp[i>>
1]
代码:
vector<int> countBits(int num)
{
vector<int>dp(num+1,0);
for(int i=1;i<=num;++i)
{
dp[i]=i&1?dp[i-1]+1:dp[i>>1];// 等价于dp[i] = dp[i&(i-1)] + 1;
} //若二进制数以1结尾 相比于前一个数字 它的1的个数增加了1 即dp[i-1]+1(二进制特点)
// 若二进制数以0结尾 将其右移一位 即末尾0消失 但其1的个数不变 即dp[i]=dp[i>>1]
return dp;
}