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: 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.
Hint:
- You should make use of what you have produced already.
- Divide the numbers in ranges like [2-3], [4-7], [8-15] and so on. And try to generate new range from previous.
- Or does the odd/even status of the number help you in calculating the number of 1s?
题目大意:
给定一个非负整数num。对于每一个满足0 ≤ i ≤ num的数字i,计算其数字的二进制表示中1的个数,并以数组形式返回。
测试用例如题目描述。
进一步思考:
很容易想到运行时间 O(n*sizeof(integer)) 的解法。但你可以用线性时间O(n)的一趟算法完成吗?
空间复杂度应当为O(n)。
你可以像老板那样吗?不要使用任何内建函数(比如C++的__builtin_popcount)。
提示:
- 你应当利用已经生成的结果。
- 将数字拆分为诸如 [2-3], [4-7], [8-15] 之类的范围。并且尝试根据已经生成的范围产生新的范围。
- 数字的奇偶性可以帮助你计算1的个数吗?
解法一:
给定num,对于每个 0<= i <=num , 计算i的2进制中1的个数。
若对每个数,进行每位的判断,时间复杂度是O(n*logn)。
可以从每个数的最低位开始分析,例如1001001 ,它的二进制1的个数等于100100 总二进制个数 + 1 。即 f = f/2 + (f 的最低位)
1 class Solution { 2 public: 3 vector<int> countBits(int num) { 4 vector<int> v(num+1, 0); 5 for(int i = 1; i < num+1; i++){ 6 v[i] = v[i >> 1] + (i & 1); 7 } 8 return v; 9 } 10 };
解法二:按位与。i & (i-1) 清除了i中最右边的1.
v[i] = v[i & (i-1)] + 1;
1 class Solution { 2 public: 3 vector<int> countBits(int num) { 4 vector<int> v(num+1, 0); 5 for(int i = 1; i < num+1; i++){ 6 v[i] = v[i & (i-1)] + 1; 7 } 8 return v; 9 } 10 };
解法三:可以从n的最高位入手,
递推式:v[n] = v[n - highbits(n)] + 1
其中highbits(n)
表示只保留n的最高位得到的数字。
越努力,越幸运