Skip to content

Commit 77bc6d7

Browse files
authored
feat: add solutions to lc problem: No.0474 (#4827)
1 parent bb6566b commit 77bc6d7

File tree

4 files changed

+160
-5
lines changed

4 files changed

+160
-5
lines changed

solution/0400-0499/0474.Ones and Zeroes/README.md

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,6 @@ tags:
7777

7878
时间复杂度 $O(sz \times m \times n)$,空间复杂度 $O(sz \times m \times n)$。其中 $sz$ 是数组 $strs$ 的长度;而 $m$ 和 $n$ 分别是字符串中 $0$ 和 $1$ 的数量上限。
7979

80-
我们注意到 $f[i][j][k]$ 的计算只和 $f[i-1][j][k]$ 以及 $f[i-1][j-a][k-b]$ 有关,因此我们可以去掉第一维,将空间复杂度优化到 $O(m \times n)$。
81-
8280
<!-- tabs:start -->
8381

8482
#### Python3
@@ -221,13 +219,41 @@ function findMaxForm(strs: string[], m: number, n: number): number {
221219
}
222220
```
223221

222+
#### Rust
223+
224+
```rust
225+
impl Solution {
226+
pub fn find_max_form(strs: Vec<String>, m: i32, n: i32) -> i32 {
227+
let sz = strs.len();
228+
let m = m as usize;
229+
let n = n as usize;
230+
let mut f = vec![vec![vec![0; n + 1]; m + 1]; sz + 1];
231+
for i in 1..=sz {
232+
let a = strs[i - 1].chars().filter(|&c| c == '0').count();
233+
let b = strs[i - 1].len() - a;
234+
for j in 0..=m {
235+
for k in 0..=n {
236+
f[i][j][k] = f[i - 1][j][k];
237+
if j >= a && k >= b {
238+
f[i][j][k] = f[i][j][k].max(f[i - 1][j - a][k - b] + 1);
239+
}
240+
}
241+
}
242+
}
243+
f[sz][m][n] as i32
244+
}
245+
}
246+
```
247+
224248
<!-- tabs:end -->
225249

226250
<!-- solution:end -->
227251

228252
<!-- solution:start -->
229253

230-
### 方法二
254+
### 方法二:动态规划(空间优化)
255+
256+
我们注意到 $f[i][j][k]$ 的计算只和 $f[i-1][j][k]$ 以及 $f[i-1][j-a][k-b]$ 有关,因此我们可以去掉第一维,将空间复杂度优化到 $O(m \times n)$。
231257

232258
<!-- tabs:start -->
233259

@@ -347,6 +373,30 @@ function findMaxForm(strs: string[], m: number, n: number): number {
347373
}
348374
```
349375

376+
#### Rust
377+
378+
```rust
379+
impl Solution {
380+
pub fn find_max_form(strs: Vec<String>, m: i32, n: i32) -> i32 {
381+
let m = m as usize;
382+
let n = n as usize;
383+
let mut f = vec![vec![0; n + 1]; m + 1];
384+
385+
for s in strs {
386+
let a = s.chars().filter(|&c| c == '0').count();
387+
let b = s.len() - a;
388+
for i in (a..=m).rev() {
389+
for j in (b..=n).rev() {
390+
f[i][j] = f[i][j].max(f[i - a][j - b] + 1);
391+
}
392+
}
393+
}
394+
395+
f[m][n]
396+
}
397+
}
398+
```
399+
350400
<!-- tabs:end -->
351401

352402
<!-- solution:end -->

solution/0400-0499/0474.Ones and Zeroes/README_EN.md

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,20 @@ Other valid but smaller subsets include {&quot;0001&quot;, &quot;1&quot;} and {&
5959

6060
<!-- solution:start -->
6161

62-
### Solution 1
62+
### Solution 1: Dynamic Programming
63+
64+
We define $f[i][j][k]$ as the maximum number of strings that can be obtained from the first $i$ strings using $j$ zeros and $k$ ones. Initially, $f[i][j][k]=0$, and the answer is $f[sz][m][n]$, where $sz$ is the length of the array $strs$.
65+
66+
For $f[i][j][k]$, we have two choices:
67+
68+
- Do not select the $i$-th string, in which case $f[i][j][k]=f[i-1][j][k]$;
69+
- Select the $i$-th string, in which case $f[i][j][k]=f[i-1][j-a][k-b]+1$, where $a$ and $b$ are the number of zeros and ones in the $i$-th string, respectively.
70+
71+
We take the maximum of these two choices to obtain the value of $f[i][j][k]$.
72+
73+
The final answer is $f[sz][m][n]$.
74+
75+
The time complexity is $O(sz \times m \times n)$, and the space complexity is $O(sz \times m \times n)$, where $sz$ is the length of the array $strs$, and $m$ and $n$ are the upper limits on the number of zeros and ones, respectively.
6376

6477
<!-- tabs:start -->
6578

@@ -203,13 +216,41 @@ function findMaxForm(strs: string[], m: number, n: number): number {
203216
}
204217
```
205218

219+
#### Rust
220+
221+
```rust
222+
impl Solution {
223+
pub fn find_max_form(strs: Vec<String>, m: i32, n: i32) -> i32 {
224+
let sz = strs.len();
225+
let m = m as usize;
226+
let n = n as usize;
227+
let mut f = vec![vec![vec![0; n + 1]; m + 1]; sz + 1];
228+
for i in 1..=sz {
229+
let a = strs[i - 1].chars().filter(|&c| c == '0').count();
230+
let b = strs[i - 1].len() - a;
231+
for j in 0..=m {
232+
for k in 0..=n {
233+
f[i][j][k] = f[i - 1][j][k];
234+
if j >= a && k >= b {
235+
f[i][j][k] = f[i][j][k].max(f[i - 1][j - a][k - b] + 1);
236+
}
237+
}
238+
}
239+
}
240+
f[sz][m][n] as i32
241+
}
242+
}
243+
```
244+
206245
<!-- tabs:end -->
207246

208247
<!-- solution:end -->
209248

210249
<!-- solution:start -->
211250

212-
### Solution 2
251+
### Solution 2: Dynamic Programming (Space Optimization)
252+
253+
We notice that the calculation of $f[i][j][k]$ only depends on $f[i-1][j][k]$ and $f[i-1][j-a][k-b]$. Therefore, we can eliminate the first dimension and optimize the space complexity to $O(m \times n)$.
213254

214255
<!-- tabs:start -->
215256

@@ -329,6 +370,30 @@ function findMaxForm(strs: string[], m: number, n: number): number {
329370
}
330371
```
331372

373+
#### Rust
374+
375+
```rust
376+
impl Solution {
377+
pub fn find_max_form(strs: Vec<String>, m: i32, n: i32) -> i32 {
378+
let m = m as usize;
379+
let n = n as usize;
380+
let mut f = vec![vec![0; n + 1]; m + 1];
381+
382+
for s in strs {
383+
let a = s.chars().filter(|&c| c == '0').count();
384+
let b = s.len() - a;
385+
for i in (a..=m).rev() {
386+
for j in (b..=n).rev() {
387+
f[i][j] = f[i][j].max(f[i - a][j - b] + 1);
388+
}
389+
}
390+
}
391+
392+
f[m][n]
393+
}
394+
}
395+
```
396+
332397
<!-- tabs:end -->
333398

334399
<!-- solution:end -->
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
impl Solution {
2+
pub fn find_max_form(strs: Vec<String>, m: i32, n: i32) -> i32 {
3+
let sz = strs.len();
4+
let m = m as usize;
5+
let n = n as usize;
6+
let mut f = vec![vec![vec![0; n + 1]; m + 1]; sz + 1];
7+
for i in 1..=sz {
8+
let a = strs[i - 1].chars().filter(|&c| c == '0').count();
9+
let b = strs[i - 1].len() - a;
10+
for j in 0..=m {
11+
for k in 0..=n {
12+
f[i][j][k] = f[i - 1][j][k];
13+
if j >= a && k >= b {
14+
f[i][j][k] = f[i][j][k].max(f[i - 1][j - a][k - b] + 1);
15+
}
16+
}
17+
}
18+
}
19+
f[sz][m][n] as i32
20+
}
21+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
impl Solution {
2+
pub fn find_max_form(strs: Vec<String>, m: i32, n: i32) -> i32 {
3+
let m = m as usize;
4+
let n = n as usize;
5+
let mut f = vec![vec![0; n + 1]; m + 1];
6+
7+
for s in strs {
8+
let a = s.chars().filter(|&c| c == '0').count();
9+
let b = s.len() - a;
10+
for i in (a..=m).rev() {
11+
for j in (b..=n).rev() {
12+
f[i][j] = f[i][j].max(f[i - a][j - b] + 1);
13+
}
14+
}
15+
}
16+
17+
f[m][n]
18+
}
19+
}

0 commit comments

Comments
 (0)