算法设计与分析课作业【week12】leetcode--338. Counting Bits

题目

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;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值