不积跬步,无以至千里;不积小流,无以成江海。——荀子

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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].

Follow up:

    • It is very easy to come up with a solution with run time O(n*sizeof(integer)). But can you do it in linear time O(n) /possibly in a single pass?
    • Space complexity should be O(n).
    • Can you do it like a boss? Do it without using any builtin function like __builtin_popcount in c++ or in any other language.

 

  题目大意:给定一个非负整数num,计算出0~num之间每个整数(二进制表示)各自包含的1的个数。要求:时间复杂度和空间复杂度均为O(n)。

  题目思路:若b=n&(n-1),则b中包含1的个数为n中包含1的个数减1。如n=10110,则b=10110&(10110-1)=10110&10101=10100,b中包含1的个数为2,n中包含1的个数为3。

  因此这道题可以利用这个思路,求n中包含1的个数时,只要求出n&(n-1)包含1的个数然后加1即可。由于n&(n-1)一定小于n,因此n&(n-1)中包含1的个数在计算n时已经计算好了。因此代码如下:

class Solution {
public:
    vector<int> countBits(int num) {
        vector<int> ret(num+1,0);
        for(int i=1;i<=num;i++)
            ret[i]=ret[i&(i-1)]+1;
        return ret;
    }
};

 

  另外,利用上面的思路,当只要我们求正整数n中包含1的个数时,可以这么实现:

int countBit_1(int n)
{
    int count = 0;
    while (n)
    {
        n = n&(n - 1);
        count++;
    }
    return count;
}

 

  另外,这道题还有一种解法:

  b=n/2=n>>1,若n为偶数,则b中包含1的个数与n一样;若n为奇数,则b中包含1的个数为n中包含1的个数减1。

  如当n=10=(1010)2时,b=n>>1=101,b中包含1的个数与n一样;

  当n=11=(1011)2时,b=n>>1=101,b中包含1的个数为n中包含1的个数减1。

class Solution {
public:
    vector<int> countBits(int num) {
        vector<int> ret(num+1,0);
        for(int i = 1; i <= num; i++)
        {
            ret[i] = ret[i/2];
            if(i%2 == 1) ret[i]++; 
        }
        return ret;
    }
};

 

posted on 2017-09-24 00:37  hejunlin  阅读(184)  评论(0编辑  收藏  举报