[LeetCode] 338. Counting Bits
Given an integer n
, return an array ans
of length n + 1
such that for each i
(0 <= i <= n
), ans[i]
is the number of 1
's in the binary representation of i
.
Example 1:
Input: n = 2 Output: [0,1,1] Explanation: 0 --> 0 1 --> 1 2 --> 10
Example 2:
Input: n = 5 Output: [0,1,1,2,1,2] Explanation: 0 --> 0 1 --> 1 2 --> 10 3 --> 11 4 --> 100 5 --> 101
Constraints:
0 <= n <= 105
Follow up:
- It is very easy to come up with a solution with a runtime of
O(n log n)
. Can you do it in linear timeO(n)
and possibly in a single pass? - Can you do it without using any built-in function (i.e., like
__builtin_popcount
in C++)?
比特位计数。
给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/counting-bits
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题意是给定一个非负整数 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 };
二刷我再提供一个朴素解法,对于每个数字 i 而言,我们就用笨办法去看一下他的二进制到底有多少个 1。
时间O(n) - n 个数字,每个数字看一下32位
空间O(1)
Java实现
1 class Solution { 2 public int[] countBits(int n) { 3 int[] res = new int[n + 1]; 4 // corner case 5 if (n == 0) { 6 return res; 7 } 8 9 // normal case 10 for (int i = 1; i <= n; i++) { 11 res[i] = helper(i); 12 } 13 return res; 14 } 15 16 private int helper(int i) { 17 int count = 0; 18 while (i != 0) { 19 if ((i & 1) == 1) { 20 count++; 21 } 22 i >>= 1; 23 } 24 return count; 25 } 26 }