Skip to content

Commit f82e843

Browse files
authored
feat: add solutions to lc problem: No.0474 (#1677)
No.0474.Ones and Zeroes
1 parent 4240dff commit f82e843

File tree

7 files changed

+491
-199
lines changed

7 files changed

+491
-199
lines changed

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

+217-68
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,22 @@
4848

4949
<!-- 这里可写通用的实现逻辑 -->
5050

51-
题目可以转换为 `0-1` 背包问题,在 k 个字符串中选出一些字符串(每个字符串只能使用一次),并且满足字符串最多包含 m 个 0 和 n 个 1,求满足此条件的字符串的最大长度(字符串个数)。
51+
**方法一:动态规划**
52+
53+
我们定义 $f[i][j][k]$ 表示在前 $i$ 个字符串中,使用 $j$ 个 0 和 $k$ 个 1 的情况下最多可以得到的字符串数量。初始时 $f[i][j][k]=0$,答案为 $f[sz][m][n]$,其中 $sz$ 是数组 $strs$ 的长度。
54+
55+
对于 $f[i][j][k]$,我们有两种决策:
56+
57+
- 不选第 $i$ 个字符串,此时 $f[i][j][k]=f[i-1][j][k]$;
58+
- 选第 $i$ 个字符串,此时 $f[i][j][k]=f[i-1][j-a][k-b]+1$,其中 $a$ 和 $b$ 分别是第 $i$ 个字符串中 $0$ 和 $1$ 的数量。
59+
60+
我们取两种决策中的最大值,即可得到 $f[i][j][k]$ 的值。
61+
62+
最终的答案即为 $f[sz][m][n]$。
63+
64+
时间复杂度 $O(sz \times m \times n)$,空间复杂度 $O(sz \times m \times n)$。其中 $sz$ 是数组 $strs$ 的长度;而 $m$ 和 $n$ 分别是字符串中 $0$ 和 $1$ 的数量上限。
65+
66+
我们注意到 $f[i][j][k]$ 的计算只和 $f[i-1][j][k]$ 以及 $f[i-1][j-a][k-b]$ 有关,因此我们可以去掉第一维,将空间复杂度优化到 $O(m \times n)$。
5267

5368
<!-- tabs:start -->
5469

@@ -59,39 +74,28 @@
5974
```python
6075
class Solution:
6176
def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
62-
l = len(strs)
63-
dp = [[[0] * (n + 1) for i in range(m + 1)] for j in range(l)]
64-
t = [(s.count('0'), s.count('1')) for s in strs]
65-
n0, n1 = t[0]
66-
for j in range(m + 1):
67-
for k in range(n + 1):
68-
if n0 <= j and n1 <= k:
69-
dp[0][j][k] = 1
70-
71-
for i in range(1, l):
72-
n0, n1 = t[i]
77+
sz = len(strs)
78+
f = [[[0] * (n + 1) for _ in range(m + 1)] for _ in range(sz + 1)]
79+
for i, s in enumerate(strs, 1):
80+
a, b = s.count("0"), s.count("1")
7381
for j in range(m + 1):
7482
for k in range(n + 1):
75-
dp[i][j][k] = dp[i - 1][j][k]
76-
if n0 <= j and n1 <= k:
77-
dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - n0][k - n1] + 1)
78-
79-
return dp[-1][-1][-1]
83+
f[i][j][k] = f[i - 1][j][k]
84+
if j >= a and k >= b:
85+
f[i][j][k] = max(f[i][j][k], f[i - 1][j - a][k - b] + 1)
86+
return f[sz][m][n]
8087
```
8188

82-
空间优化:
83-
8489
```python
8590
class Solution:
8691
def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
87-
dp = [[0] * (n + 1) for _ in range(m + 1)]
88-
t = [(s.count('0'), s.count('1')) for s in strs]
89-
for k in range(len(strs)):
90-
n0, n1 = t[k]
91-
for i in range(m, n0 - 1, -1):
92-
for j in range(n, n1 - 1, -1):
93-
dp[i][j] = max(dp[i][j], dp[i - n0][j - n1] + 1)
94-
return dp[-1][-1]
92+
f = [[0] * (n + 1) for _ in range(m + 1)]
93+
for s in strs:
94+
a, b = s.count("0"), s.count("1")
95+
for i in range(m, a - 1, -1):
96+
for j in range(n, b - 1, -1):
97+
f[i][j] = max(f[i][j], f[i - a][j - b] + 1)
98+
return f[m][n]
9599
```
96100

97101
### **Java**
@@ -100,24 +104,56 @@ class Solution:
100104

101105
```java
102106
class Solution {
103-
public : int findMaxForm(vector<string>& strs, int m, int n) {
104-
vector<vector<int>> dp(m + 1, vector<int>(n + 1));
105-
for (auto s : strs) {
106-
vector<int> t = count(s);
107-
for (int i = m; i >= t[0]; --i)
108-
for (int j = n; j >= t[1]; --j)
109-
dp[i][j] = max(dp[i][j], dp[i - t[0]][j - t[1]] + 1);
107+
public int findMaxForm(String[] strs, int m, int n) {
108+
int sz = strs.length;
109+
int[][][] f = new int[sz + 1][m + 1][n + 1];
110+
for (int i = 1; i <= sz; ++i) {
111+
int[] cnt = count(strs[i - 1]);
112+
for (int j = 0; j <= m; ++j) {
113+
for (int k = 0; k <= n; ++k) {
114+
f[i][j][k] = f[i - 1][j][k];
115+
if (j >= cnt[0] && k >= cnt[1]) {
116+
f[i][j][k] = Math.max(f[i][j][k], f[i - 1][j - cnt[0]][k - cnt[1]] + 1);
117+
}
118+
}
119+
}
110120
}
111-
return dp[m][n];
121+
return f[sz][m][n];
112122
}
113123

114-
vector<int> count(string s) {
115-
int n0 = 0;
116-
for (char c : s)
117-
if (c == '0') ++n0;
118-
return {n0, (int) s.size() - n0};
124+
private int[] count(String s) {
125+
int[] cnt = new int[2];
126+
for (int i = 0; i < s.length(); ++i) {
127+
++cnt[s.charAt(i) - '0'];
128+
}
129+
return cnt;
119130
}
120-
};
131+
}
132+
```
133+
134+
```java
135+
class Solution {
136+
public int findMaxForm(String[] strs, int m, int n) {
137+
int[][] f = new int[m + 1][n + 1];
138+
for (String s : strs) {
139+
int[] cnt = count(s);
140+
for (int i = m; i >= cnt[0]; --i) {
141+
for (int j = n; j >= cnt[1]; --j) {
142+
f[i][j] = Math.max(f[i][j], f[i - cnt[0]][j - cnt[1]] + 1);
143+
}
144+
}
145+
}
146+
return f[m][n];
147+
}
148+
149+
private int[] count(String s) {
150+
int[] cnt = new int[2];
151+
for (int i = 0; i < s.length(); ++i) {
152+
++cnt[s.charAt(i) - '0'];
153+
}
154+
return cnt;
155+
}
156+
}
121157
```
122158

123159
### **C++**
@@ -126,21 +162,50 @@ class Solution {
126162
class Solution {
127163
public:
128164
int findMaxForm(vector<string>& strs, int m, int n) {
129-
vector<vector<int>> dp(m + 1, vector<int>(n + 1));
130-
for (int k = 0; k < strs.size(); ++k) {
131-
vector<int> t = count(strs[k]);
132-
for (int i = m; i >= t[0]; --i)
133-
for (int j = n; j >= t[1]; --j)
134-
dp[i][j] = max(dp[i][j], dp[i - t[0]][j - t[1]] + 1);
165+
int sz = strs.size();
166+
int f[sz + 1][m + 1][n + 1];
167+
memset(f, 0, sizeof(f));
168+
for (int i = 1; i <= sz; ++i) {
169+
auto [a, b] = count(strs[i - 1]);
170+
for (int j = 0; j <= m; ++j) {
171+
for (int k = 0; k <= n; ++k) {
172+
f[i][j][k] = f[i - 1][j][k];
173+
if (j >= a && k >= b) {
174+
f[i][j][k] = max(f[i][j][k], f[i - 1][j - a][k - b] + 1);
175+
}
176+
}
177+
}
178+
}
179+
return f[sz][m][n];
180+
}
181+
182+
pair<int, int> count(string& s) {
183+
int a = count_if(s.begin(), s.end(), [](char c) { return c == '0'; });
184+
return {a, s.size() - a};
185+
}
186+
};
187+
```
188+
189+
```cpp
190+
class Solution {
191+
public:
192+
int findMaxForm(vector<string>& strs, int m, int n) {
193+
int f[m + 1][n + 1];
194+
memset(f, 0, sizeof(f));
195+
for (auto& s : strs) {
196+
auto [a, b] = count(s);
197+
for (int i = m; i >= a; --i) {
198+
for (int j = n; j >= b; --j) {
199+
f[i][j] = max(f[i][j], f[i - a][j - b] + 1);
200+
}
201+
}
135202
}
136-
return dp[m][n];
203+
return f[m][n];
137204
}
138205

139-
vector<int> count(string s) {
140-
int n0 = 0;
141-
for (char c : s)
142-
if (c == '0') ++n0;
143-
return {n0, (int) s.size() - n0};
206+
pair<int, int> count(string& s) {
207+
int a = count_if(s.begin(), s.end(), [](char c) { return c == '0'; });
208+
return {a, s.size() - a};
144209
}
145210
};
146211
```
@@ -149,29 +214,61 @@ public:
149214

150215
```go
151216
func findMaxForm(strs []string, m int, n int) int {
152-
dp := make([][]int, m+1)
153-
for i := 0; i < m+1; i++ {
154-
dp[i] = make([]int, n+1)
217+
sz := len(strs)
218+
f := make([][][]int, sz+1)
219+
for i := range f {
220+
f[i] = make([][]int, m+1)
221+
for j := range f[i] {
222+
f[i][j] = make([]int, n+1)
223+
}
155224
}
156-
for _, s := range strs {
157-
t := count(s)
158-
for i := m; i >= t[0]; i-- {
159-
for j := n; j >= t[1]; j-- {
160-
dp[i][j] = max(dp[i][j], dp[i-t[0]][j-t[1]]+1)
225+
for i := 1; i <= sz; i++ {
226+
a, b := count(strs[i-1])
227+
for j := 0; j <= m; j++ {
228+
for k := 0; k <= n; k++ {
229+
f[i][j][k] = f[i-1][j][k]
230+
if j >= a && k >= b {
231+
f[i][j][k] = max(f[i][j][k], f[i-1][j-a][k-b]+1)
232+
}
161233
}
162234
}
163235
}
164-
return dp[m][n]
236+
return f[sz][m][n]
237+
}
238+
239+
func count(s string) (int, int) {
240+
a := strings.Count(s, "0")
241+
return a, len(s) - a
242+
}
243+
244+
func max(a, b int) int {
245+
if a > b {
246+
return a
247+
}
248+
return b
165249
}
250+
```
166251

167-
func count(s string) []int {
168-
n0 := 0
169-
for i := 0; i < len(s); i++ {
170-
if s[i] == '0' {
171-
n0++
252+
```go
253+
func findMaxForm(strs []string, m int, n int) int {
254+
f := make([][]int, m+1)
255+
for i := range f {
256+
f[i] = make([]int, n+1)
257+
}
258+
for _, s := range strs {
259+
a, b := count(s)
260+
for j := m; j >= a; j-- {
261+
for k := n; k >= b; k-- {
262+
f[j][k] = max(f[j][k], f[j-a][k-b]+1)
263+
}
172264
}
173265
}
174-
return []int{n0, len(s) - n0}
266+
return f[m][n]
267+
}
268+
269+
func count(s string) (int, int) {
270+
a := strings.Count(s, "0")
271+
return a, len(s) - a
175272
}
176273

177274
func max(a, b int) int {
@@ -182,6 +279,58 @@ func max(a, b int) int {
182279
}
183280
```
184281

282+
### **TypeScript**
283+
284+
```ts
285+
function findMaxForm(strs: string[], m: number, n: number): number {
286+
const sz = strs.length;
287+
const f = Array.from({ length: sz + 1 }, () =>
288+
Array.from({ length: m + 1 }, () => Array.from({ length: n + 1 }, () => 0)),
289+
);
290+
const count = (s: string): [number, number] => {
291+
let a = 0;
292+
for (const c of s) {
293+
a += c === '0' ? 1 : 0;
294+
}
295+
return [a, s.length - a];
296+
};
297+
for (let i = 1; i <= sz; ++i) {
298+
const [a, b] = count(strs[i - 1]);
299+
for (let j = 0; j <= m; ++j) {
300+
for (let k = 0; k <= n; ++k) {
301+
f[i][j][k] = f[i - 1][j][k];
302+
if (j >= a && k >= b) {
303+
f[i][j][k] = Math.max(f[i][j][k], f[i - 1][j - a][k - b] + 1);
304+
}
305+
}
306+
}
307+
}
308+
return f[sz][m][n];
309+
}
310+
```
311+
312+
```ts
313+
function findMaxForm(strs: string[], m: number, n: number): number {
314+
const f = Array.from({ length: m + 1 }, () => Array.from({ length: n + 1 }, () => 0));
315+
const count = (s: string): [number, number] => {
316+
let a = 0;
317+
for (const c of s) {
318+
a += c === '0' ? 1 : 0;
319+
}
320+
return [a, s.length - a];
321+
};
322+
for (const s of strs) {
323+
const [a, b] = count(s);
324+
for (let i = m; i >= a; --i) {
325+
for (let j = n; j >= b; --j) {
326+
f[i][j] = Math.max(f[i][j], f[i - a][j - b] + 1);
327+
}
328+
}
329+
}
330+
return f[m][n];
331+
}
332+
```
333+
185334
### **...**
186335

187336
```

0 commit comments

Comments
 (0)