[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:
Fornum = 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