题目
Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary representation and return them as an array.
Example 1:
Input: 2
Output: [0,1,1]
Example 2:
Input: 5
Output:
[0,1,1,2,1,2]
题目的要求是输入一个数,数出从0到该数的每个数的二进制表示中1的个数。我们一一列出0到10的二进制数找下规律:
0、1、01、10、11、100、101、110、111、1000、1001、1010。
我们首先看到是偶数的二进制末尾都会是0,而奇数都会是1。再稍微看一下就会发现,每个奇数都是前一个偶数加1,而1的个数也是比前面的偶数多1位。所以我们首先可以得到奇数的1的个数的算法:当i为奇数时:该奇数的二进制1的个数 bits[i] = bit[i - 1] + 1。
接下来我们就要解决偶数的二进制表示1的个数的计算。
我们再把偶数的二进制单独抽出来观察:(以2、4、6、8、10、12为例)
10、100、110、1000、1010、1100。
偶数的二进制表示末尾一直是0,对于1的个数的计算并没有影响,那如果我们把这末尾的0去掉的话,再看看去掉后剩下的样子:
1、10、11、100、101、110。
即偶数除以2,我们可以发现,每个偶数的二进制表示的1的个数会跟其除以2的数的二进制表示1的个数完全相同。
这样我们也得出了偶数的二进制表示1的个数计算方式:(i为偶数)bits[i] = bit[i / 2]
这样从0开始,以动态规划的方法,从头遍历,我们就得到了答案。
C++代码如下:
class Solution {
public:
vector<int> countBits(int num) {
vector<int> bits;
bits.push_back(0);
for(int i = 1; i <= num; ++i) {
if (i % 2)
bits.push_back(bits[i - 1] + 1);
else
bits.push_back(bits[i / 2]);
}
return bits;
}
};