Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f82e843

Browse files
feat: add solutions to lc problem: No.0474 (doocs#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‎

Lines changed: 217 additions & 68 deletions
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)

AltStyle によって変換されたページ (->オリジナル) /