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 1:
Input: 2 Output: [0,1,1]
Example 2:
Input: 5 Output:
[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 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。如上第二个例子,如果input是5,那么从0到5,每个数字转换成二进制之后,包含的1的个数就是0,1,1,2,1,2。
0 - 0000
1 - 0001
2 - 0010
3 - 0011
4 - 0100
5 - 0101
既然是问二进制数中包含的1的个数,不难发现二进制数有如下规律
- 如果 i 是奇数,那么 i 和 i + 1 中 1 的数目只差一个,比如2和3;
- 如果 i 是偶数,那么 i 中包含的 1 的个数跟 i / 2 相同,因为某个数字乘以2就是左移一位,除以2就是右移一位
有了这个规律,代码就比较直观了。设 dp[i] 是第 i 个数字包含的 1 的个数。如果 i 是奇数,dp[i] = dp[i - 1] + 1;如果 i 是偶数,dp[i] = dp[i / 2]。
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public int[] countBits(int num) { 3 int[] dp = new int[num + 1]; 4 dp[0] = 0; 5 for (int i = 1; i <= num; i++) { 6 if (i % 2 == 0) { 7 dp[i] = dp[i / 2]; 8 } else { 9 dp[i] = dp[i - 1] + 1; 10 } 11 } 12 return dp; 13 } 14 }
JavaScript实现
1 /** 2 * @param {number} num 3 * @return {number[]} 4 */ 5 var countBits = function (num) { 6 let dp = new Array(num + 1); 7 dp[0] = 0; 8 for (let i = 1; i <= num; i++) { 9 if (i % 2 == 0) { 10 dp[i] = dp[i / 2]; 11 } else { 12 dp[i] = dp[i - 1] + 1; 13 } 14 } 15 return dp; 16 };