diff --git a/solution/0400-0499/0474.Ones and Zeroes/README.md b/solution/0400-0499/0474.Ones and Zeroes/README.md index ab93b2b70ac7d..87593850a933e 100644 --- a/solution/0400-0499/0474.Ones and Zeroes/README.md +++ b/solution/0400-0499/0474.Ones and Zeroes/README.md @@ -77,8 +77,6 @@ tags: 时间复杂度 $O(sz \times m \times n)$,空间复杂度 $O(sz \times m \times n)$。其中 $sz$ 是数组 $strs$ 的长度;而 $m$ 和 $n$ 分别是字符串中 $0$ 和 $1$ 的数量上限。 -我们注意到 $f[i][j][k]$ 的计算只和 $f[i-1][j][k]$ 以及 $f[i-1][j-a][k-b]$ 有关,因此我们可以去掉第一维,将空间复杂度优化到 $O(m \times n)$。 - #### Python3 @@ -221,13 +219,41 @@ function findMaxForm(strs: string[], m: number, n: number): number { } ``` +#### Rust + +```rust +impl Solution { + pub fn find_max_form(strs: Vec, m: i32, n: i32) -> i32 { + let sz = strs.len(); + let m = m as usize; + let n = n as usize; + let mut f = vec![vec![vec![0; n + 1]; m + 1]; sz + 1]; + for i in 1..=sz { + let a = strs[i - 1].chars().filter(|&c| c == '0').count(); + let b = strs[i - 1].len() - a; + for j in 0..=m { + for k in 0..=n { + f[i][j][k] = f[i - 1][j][k]; + if j >= a && k >= b { + f[i][j][k] = f[i][j][k].max(f[i - 1][j - a][k - b] + 1); + } + } + } + } + f[sz][m][n] as i32 + } +} +``` + -### 方法二 +### 方法二:动态规划(空间优化) + +我们注意到 $f[i][j][k]$ 的计算只和 $f[i-1][j][k]$ 以及 $f[i-1][j-a][k-b]$ 有关,因此我们可以去掉第一维,将空间复杂度优化到 $O(m \times n)$。 @@ -347,6 +373,30 @@ function findMaxForm(strs: string[], m: number, n: number): number { } ``` +#### Rust + +```rust +impl Solution { + pub fn find_max_form(strs: Vec, m: i32, n: i32) -> i32 { + let m = m as usize; + let n = n as usize; + let mut f = vec![vec![0; n + 1]; m + 1]; + + for s in strs { + let a = s.chars().filter(|&c| c == '0').count(); + let b = s.len() - a; + for i in (a..=m).rev() { + for j in (b..=n).rev() { + f[i][j] = f[i][j].max(f[i - a][j - b] + 1); + } + } + } + + f[m][n] + } +} +``` + diff --git a/solution/0400-0499/0474.Ones and Zeroes/README_EN.md b/solution/0400-0499/0474.Ones and Zeroes/README_EN.md index 8e6f9112a9049..d0ff8271075ae 100644 --- a/solution/0400-0499/0474.Ones and Zeroes/README_EN.md +++ b/solution/0400-0499/0474.Ones and Zeroes/README_EN.md @@ -59,7 +59,20 @@ Other valid but smaller subsets include {"0001", "1"} and {& -### Solution 1 +### Solution 1: Dynamic Programming + +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$. + +For $f[i][j][k]$, we have two choices: + +- Do not select the $i$-th string, in which case $f[i][j][k]=f[i-1][j][k]$; +- 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. + +We take the maximum of these two choices to obtain the value of $f[i][j][k]$. + +The final answer is $f[sz][m][n]$. + +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. @@ -203,13 +216,41 @@ function findMaxForm(strs: string[], m: number, n: number): number { } ``` +#### Rust + +```rust +impl Solution { + pub fn find_max_form(strs: Vec, m: i32, n: i32) -> i32 { + let sz = strs.len(); + let m = m as usize; + let n = n as usize; + let mut f = vec![vec![vec![0; n + 1]; m + 1]; sz + 1]; + for i in 1..=sz { + let a = strs[i - 1].chars().filter(|&c| c == '0').count(); + let b = strs[i - 1].len() - a; + for j in 0..=m { + for k in 0..=n { + f[i][j][k] = f[i - 1][j][k]; + if j >= a && k >= b { + f[i][j][k] = f[i][j][k].max(f[i - 1][j - a][k - b] + 1); + } + } + } + } + f[sz][m][n] as i32 + } +} +``` + -### Solution 2 +### Solution 2: Dynamic Programming (Space Optimization) + +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)$. @@ -329,6 +370,30 @@ function findMaxForm(strs: string[], m: number, n: number): number { } ``` +#### Rust + +```rust +impl Solution { + pub fn find_max_form(strs: Vec, m: i32, n: i32) -> i32 { + let m = m as usize; + let n = n as usize; + let mut f = vec![vec![0; n + 1]; m + 1]; + + for s in strs { + let a = s.chars().filter(|&c| c == '0').count(); + let b = s.len() - a; + for i in (a..=m).rev() { + for j in (b..=n).rev() { + f[i][j] = f[i][j].max(f[i - a][j - b] + 1); + } + } + } + + f[m][n] + } +} +``` + diff --git a/solution/0400-0499/0474.Ones and Zeroes/Solution.rs b/solution/0400-0499/0474.Ones and Zeroes/Solution.rs new file mode 100644 index 0000000000000..d8643d6a938d5 --- /dev/null +++ b/solution/0400-0499/0474.Ones and Zeroes/Solution.rs @@ -0,0 +1,21 @@ +impl Solution { + pub fn find_max_form(strs: Vec, m: i32, n: i32) -> i32 { + let sz = strs.len(); + let m = m as usize; + let n = n as usize; + let mut f = vec![vec![vec![0; n + 1]; m + 1]; sz + 1]; + for i in 1..=sz { + let a = strs[i - 1].chars().filter(|&c| c == '0').count(); + let b = strs[i - 1].len() - a; + for j in 0..=m { + for k in 0..=n { + f[i][j][k] = f[i - 1][j][k]; + if j >= a && k >= b { + f[i][j][k] = f[i][j][k].max(f[i - 1][j - a][k - b] + 1); + } + } + } + } + f[sz][m][n] as i32 + } +} diff --git a/solution/0400-0499/0474.Ones and Zeroes/Solution2.rs b/solution/0400-0499/0474.Ones and Zeroes/Solution2.rs new file mode 100644 index 0000000000000..7c62b38f48c01 --- /dev/null +++ b/solution/0400-0499/0474.Ones and Zeroes/Solution2.rs @@ -0,0 +1,19 @@ +impl Solution { + pub fn find_max_form(strs: Vec, m: i32, n: i32) -> i32 { + let m = m as usize; + let n = n as usize; + let mut f = vec![vec![0; n + 1]; m + 1]; + + for s in strs { + let a = s.chars().filter(|&c| c == '0').count(); + let b = s.len() - a; + for i in (a..=m).rev() { + for j in (b..=n).rev() { + f[i][j] = f[i][j].max(f[i - a][j - b] + 1); + } + } + } + + f[m][n] + } +}