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; } };
原文:http://www.cnblogs.com/hejunlin1992/p/7583651.html