[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 time O(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 }

 

LeetCode 题目总结

posted @ 2020-05-29 01:23  CNoodle  阅读(95)  评论(0编辑  收藏  举报