leetcode 338. Counting Bits

leetcode 338. Counting Bits

Question

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

For num = 5 you should return [0,1,1,2,1,2].

问题

给定一个非负整数num,返回[1,num]区间内每个数字的二进制串中1的个数。

要求

  1. one-pass
  2. O(n)时间复杂度
  3. O(n)空间复杂度
  4. 不准用__builtin_popcount 之类的内建函数

分析

首先想到的方法,肯定是依次计算每个数字的二进制串中1的个数。计算数字的二进制串中1的个数是一个经典问题,复杂度是O(n),n是二进制串的长度。显然这样整体的复杂度就是O(n*bitof(integer)),不符合要求。
然后想办法找结果列表的规律:0 1 1 2 1 2 2 3 1 2 2 3 2 3 3 4 1…好像并没有什么规律。
那么能不能利用已经计算出来的结果呢?可以的。假设countOneBit是获取1的个数的操作,那么countOneBit(N) = countOneBit(N >> 1) + N & 1。
举个例子,假设现在要计算7的二进制串中1的个数。7的二进制串是0111,可以分成两块011 1,这两块分别对应上面的公式的两部分。

代码

vector<int> countBits(int num) {
        vector<int> bits;
        bits.push_back(0);
        for (int i = 1; i <= num; i++)
        {
            int bit = bits[i >> 1] + (i & 1);
            bits.push_back(bit);
        }

        return bits;
    }

总结

当对集合中的每个元素进行相同操作时,可以考虑使用前面已经操作完成的结果。有点动态规划的意思。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值