1. 程式人生 > >[Leetcode] 338. Counting Bits

[Leetcode] 338. Counting Bits

div number ace ever lex ould sub line lang

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

[Leetcode] 338. Counting Bits