8000 update 338 solution · zykjcom/leetcode@a16b546 · GitHub
[go: up one dir, main page]

Skip to content

Commit a16b546

Browse files
committed
update 338 solution
1 parent 3609269 commit a16b546

File tree

1 file changed

+97
-20
lines changed

1 file changed

+97
-20
lines changed

problems/338. Counting Bits/README.md

Lines changed: 97 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,114 @@
11
# 338. Counting Bits
22

3-
# Description
3+
## #1 暴力搜索[AC]
44

5-
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.
5+
### 思路
66

7-
**Example:**
8-
For `num = 5` you should return `[0,1,1,2,1,2]`.
7+
我们需要算法`0<=i<=num`这个范围内,每个数中有几个1,最直接的想法当然是遍历这个范围内的所有数值,然后求解这个数值有几个1。
98

10-
**Follow up:**
9+
### 算法
1110

12-
- 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?
13-
- Space complexity should be **O(n)**.
14-
- Can you do it like a boss? Do it without using any builtin function like **__builtin_popcount** in c++ or in any other language.
11+
```java
12+
class Solution {
13+
public int[] countBits(int num) {
14+
int[] res = new int[num+1];
15+
for(int i=0; i<res.length; i++){
16+
int count = 0;
17+
int val = i;
18+
for(int j=0; j<32; j++){
19+
if((val & 1) == 1)
20+
count++;
21+
val >>= 1;
22+
}
23+
res[i] = count;
24+
}
25+
return res;
26+
}
27+
}
28+
```
29+
30+
此外,我们还可以通过`x&=(x-1)`消除最后一个1的方式来统计`x`中到底有多少个1。
31+
32+
```java
33+
private int popcount(int x) {
34+
int count;
35+
for (count = 0; x != 0; ++count)
36+
x &= x - 1; //zeroing out the least significant nonzero bit
37+
return count;
38+
}
39+
```
40+
41+
### 复杂性分析
42+
43+
- 时间复杂性:$O(n*sizeof(interger))$
44+
- 空间复杂性:$O(n)$
45+
46+
## #2 动态规划(高位添1)[AC]
47+
48+
### 思路
49+
50+
通过观察二进制数的特点,我们发现可以在某个数a的二进制前面添1来得到更大的数b,而b中1的数量比a多1。比如:
1551

16-
# Solution
52+
$$\begin{align} (0) &= (0)_2 \\ (1) &= (1)_2 \\ (2) &= (10)_2 \\ (3) &= (11)_2 \\ \end{align}$$
1753

18-
这道题目,是关于bit操作的题目,bit操作,还不是很熟悉,这里要求出递增数值的bit表示中,1的个数。把答案抄上了,感觉还是迷迷糊糊,找个时间好好总结一下。
54+
我们发现,在数值$0$的二进制前面加1,会得到$3$,而3二进制表示法中1的个数比0的二进制表示法中1的个数多1。
55+
56+
我们记$P(x)$表示x的二进制表示法中1的个数,于是,我们得到如下的表示式子:
57+
58+
$$P(x+b) = P(x) + 1, b=2^m > x$$
59+
60+
基于这个表达式,我们可以设计出动态规划的算法来求解。
61+
62+
### 算法
1963

2064
```java
21-
class Solution {
65+
public class Solution {
2266
public int[] countBits(int num) {
23-
int[] ret = new int[num+1];
24-
ret[0] = 0;
25-
int pow = 1;
26-
for(int i=1, t=0; i<=num; i++, t++){
27-
if(i == pow){
28-
pow *= 2;
29-
t = 0;
67+
int[] ans = new int[num + 1];
68+
int i = 0, b = 1;
69+
// [0, b) is calculated
70+
while (b <= num) {
71+
// generate [b, 2b) or [b, num) from [0, b)
72+
while(i < b && i + b <= num){
73+
ans[i + b] = ans[i] + 1;
74+
++i;
3075
}
31-
ret[i] = ret[t] + 1;
76+
i = 0; // reset i
77+
b <<= 1; // b = 2b
3278
}
33-
return ret;
79+
return ans;
3480
}
3581
}
3682
```
3783

84+
### 复杂度分析:
85+
86+
- 时间复杂度:$O(n)$
87+
- 空间复杂度:$O(n)$
88+
89+
## #3 动态规划(最低位消1)[AC]
90+
91+
### 思路
92+
93+
想法和上面的类似,只是我们利用了`x&(x-1)`会去掉最后一个1的技巧,来重写我们的转移方程:
94+
95+
$$P(x+b) = P(x \& (x-1)) + 1$$
96+
97+
### 算法
98+
99+
```java
100+
public class Solution {
101+
public int[] countBits(int num) {
102+
int[] ans = new int[num + 1];
103+
for (int i = 1; i <= num; ++i)
104+
ans[i] = ans[i & (i - 1)] + 1;
105+
return ans;
106+
}
107+
}
108+
```
109+
110+
### 复杂度分析:
111+
112+
- 时间复杂度:$O(n)$
113+
- 空间复杂度:$O(n)$
114+

0 commit comments

Comments
 (0)
0