Skip to content

Commit dc4e948

Browse files
authored
feat: add solutions to lc problems: No.3129,3130 (#2682)
1 parent 4b32591 commit dc4e948

File tree

20 files changed

+1559
-16
lines changed

20 files changed

+1559
-16
lines changed

Diff for: solution/3100-3199/3129.Find All Possible Stable Binary Arrays I/README.md

+275-4
Original file line numberDiff line numberDiff line change
@@ -72,24 +72,295 @@
7272

7373
## 解法
7474

75-
### 方法一
75+
### 方法一:记忆化搜索
76+
77+
我们设计一个函数 $dfs(i, j, k)$ 表示还剩下 $i$ 个 $0$ 和 $j$ 个 $1$ 且接下来待填的数字是 $k$ 的情况下,满足题目条件的稳定二进制数组的个数。那么答案就是 $dfs(zero, one, 0) + dfs(zero, one, 1)$。
78+
79+
函数 $dfs(i, j, k)$ 的计算过程如下:
80+
81+
- 如果 $i \lt 0$ 或 $j \lt 0$,返回 $0$。
82+
- 如果 $i = 0$,那么当 $k = 1$ 且 $j \leq \text{limit}$ 时返回 $1$,否则返回 $0$。
83+
- 如果 $j = 0$,那么当 $k = 0$ 且 $i \leq \text{limit}$ 时返回 $1$,否则返回 $0$。
84+
- 如果 $k = 0$,我们考虑前一个数字是 $0$ 的情况 $dfs(i - 1, j, 0)$ 和前一个数字是 $1$ 的情况 $dfs(i - 1, j, 1)$,如果前一个数是 $0$,那么有可能使得子数组中有超过 $\text{limit}$ 个 $0$,即不允许出现倒数第 $\text{limit} + 1$ 个数是 $1$ 的情况,所以我们要减去这种情况,即 $dfs(i - \text{limit} - 1, j, 1)$。
85+
- 如果 $k = 1$,我们考虑前一个数字是 $0$ 的情况 $dfs(i, j - 1, 0)$ 和前一个数字是 $1$ 的情况 $dfs(i, j - 1, 1)$,如果前一个数是 $1$,那么有可能使得子数组中有超过 $\text{limit}$ 个 $1$,即不允许出现倒数第 $\text{limit} + 1$ 个数是 $0$ 的情况,所以我们要减去这种情况,即 $dfs(i, j - \text{limit} - 1, 0)$。
86+
87+
为了避免重复计算,我们使用记忆化搜索的方法。
88+
89+
时间复杂度 $O(zero \times one)$,空间复杂度 $O(zero \times one)$。
7690

7791
<!-- tabs:start -->
7892

7993
```python
80-
94+
class Solution:
95+
def numberOfStableArrays(self, zero: int, one: int, limit: int) -> int:
96+
@cache
97+
def dfs(i: int, j: int, k: int) -> int:
98+
if i == 0:
99+
return int(k == 1 and j <= limit)
100+
if j == 0:
101+
return int(k == 0 and i <= limit)
102+
if k == 0:
103+
return (
104+
dfs(i - 1, j, 0)
105+
+ dfs(i - 1, j, 1)
106+
- (0 if i - limit - 1 < 0 else dfs(i - limit - 1, j, 1))
107+
)
108+
return (
109+
dfs(i, j - 1, 0)
110+
+ dfs(i, j - 1, 1)
111+
- (0 if j - limit - 1 < 0 else dfs(i, j - limit - 1, 0))
112+
)
113+
114+
mod = 10**9 + 7
115+
ans = (dfs(zero, one, 0) + dfs(zero, one, 1)) % mod
116+
dfs.cache_clear()
117+
return ans
81118
```
82119

83120
```java
84-
121+
class Solution {
122+
private final int mod = (int) 1e9 + 7;
123+
private Long[][][] f;
124+
private int limit;
125+
126+
public int numberOfStableArrays(int zero, int one, int limit) {
127+
f = new Long[zero + 1][one + 1][2];
128+
this.limit = limit;
129+
return (int) ((dfs(zero, one, 0) + dfs(zero, one, 1)) % mod);
130+
}
131+
132+
private long dfs(int i, int j, int k) {
133+
if (i < 0 || j < 0) {
134+
return 0;
135+
}
136+
if (i == 0) {
137+
return k == 1 && j <= limit ? 1 : 0;
138+
}
139+
if (j == 0) {
140+
return k == 0 && i <= limit ? 1 : 0;
141+
}
142+
if (f[i][j][k] != null) {
143+
return f[i][j][k];
144+
}
145+
if (k == 0) {
146+
f[i][j][k]
147+
= (dfs(i - 1, j, 0) + dfs(i - 1, j, 1) - dfs(i - limit - 1, j, 1) + mod) % mod;
148+
} else {
149+
f[i][j][k]
150+
= (dfs(i, j - 1, 0) + dfs(i, j - 1, 1) - dfs(i, j - limit - 1, 0) + mod) % mod;
151+
}
152+
return f[i][j][k];
153+
}
154+
}
85155
```
86156

87157
```cpp
88-
158+
using ll = long long;
159+
160+
class Solution {
161+
public:
162+
int numberOfStableArrays(int zero, int one, int limit) {
163+
this->limit = limit;
164+
f = vector<vector<array<ll, 2>>>(zero + 1, vector<array<ll, 2>>(one + 1, {-1, -1}));
165+
return (dfs(zero, one, 0) + dfs(zero, one, 1)) % mod;
166+
}
167+
168+
private:
169+
const int mod = 1e9 + 7;
170+
int limit;
171+
vector<vector<array<ll, 2>>> f;
172+
173+
ll dfs(int i, int j, int k) {
174+
if (i < 0 || j < 0) {
175+
return 0;
176+
}
177+
if (i == 0) {
178+
return k == 1 && j <= limit;
179+
}
180+
if (j == 0) {
181+
return k == 0 && i <= limit;
182+
}
183+
ll& res = f[i][j][k];
184+
if (res != -1) {
185+
return res;
186+
}
187+
if (k == 0) {
188+
res = (dfs(i - 1, j, 0) + dfs(i - 1, j, 1) - dfs(i - limit - 1, j, 1) + mod) % mod;
189+
} else {
190+
res = (dfs(i, j - 1, 0) + dfs(i, j - 1, 1) - dfs(i, j - limit - 1, 0) + mod) % mod;
191+
}
192+
return res;
193+
}
194+
};
89195
```
90196

91197
```go
198+
func numberOfStableArrays(zero int, one int, limit int) int {
199+
const mod int = 1e9 + 7
200+
f := make([][][2]int, zero+1)
201+
for i := range f {
202+
f[i] = make([][2]int, one+1)
203+
for j := range f[i] {
204+
f[i][j] = [2]int{-1, -1}
205+
}
206+
}
207+
var dfs func(i, j, k int) int
208+
dfs = func(i, j, k int) int {
209+
if i < 0 || j < 0 {
210+
return 0
211+
}
212+
if i == 0 {
213+
if k == 1 && j <= limit {
214+
return 1
215+
}
216+
return 0
217+
}
218+
if j == 0 {
219+
if k == 0 && i <= limit {
220+
return 1
221+
}
222+
return 0
223+
}
224+
res := &f[i][j][k]
225+
if *res != -1 {
226+
return *res
227+
}
228+
if k == 0 {
229+
*res = (dfs(i-1, j, 0) + dfs(i-1, j, 1) - dfs(i-limit-1, j, 1) + mod) % mod
230+
} else {
231+
*res = (dfs(i, j-1, 0) + dfs(i, j-1, 1) - dfs(i, j-limit-1, 0) + mod) % mod
232+
}
233+
return *res
234+
}
235+
return (dfs(zero, one, 0) + dfs(zero, one, 1)) % mod
236+
}
237+
```
238+
239+
<!-- tabs:end -->
240+
241+
### 方法二:动态规划
242+
243+
我们也可以将方法一的记忆化搜索转换为动态规划。
244+
245+
我们定义 $f[i][j][k]$ 表示使用 $i$ 个 $0$ 和 $j$ 个 $1$ 且最后一个数字是 $k$ 的稳定二进制数组的个数。那么答案就是 $f[zero][one][0] + f[zero][one][1]$。
246+
247+
初始时,我们有 $f[i][0][0] = 1$,其中 $1 \leq i \leq \min(\text{limit}, \text{zero})$;有 $f[0][j][1] = 1$,其中 $1 \leq j \leq \min(\text{limit}, \text{one})$。
92248

249+
状态转移方程如下:
250+
251+
- $f[i][j][0] = f[i - 1][j][0] + f[i - 1][j][1] - f[i - \text{limit} - 1][j][1]$。
252+
- $f[i][j][1] = f[i][j - 1][0] + f[i][j - 1][1] - f[i][j - \text{limit} - 1][0]$。
253+
254+
时间复杂度 $O(zero \times one)$,空间复杂度 $O(zero \times one)$。
255+
256+
<!-- tabs:start -->
257+
258+
```python
259+
class Solution:
260+
def numberOfStableArrays(self, zero: int, one: int, limit: int) -> int:
261+
mod = 10**9 + 7
262+
f = [[[0, 0] for _ in range(one + 1)] for _ in range(zero + 1)]
263+
for i in range(1, min(limit, zero) + 1):
264+
f[i][0][0] = 1
265+
for j in range(1, min(limit, one) + 1):
266+
f[0][j][1] = 1
267+
for i in range(1, zero + 1):
268+
for j in range(1, one + 1):
269+
f[i][j][0] = (
270+
f[i - 1][j][0]
271+
+ f[i - 1][j][1]
272+
- (0 if i - limit - 1 < 0 else f[i - limit - 1][j][1])
273+
) % mod
274+
f[i][j][1] = (
275+
f[i][j - 1][0]
276+
+ f[i][j - 1][1]
277+
- (0 if j - limit - 1 < 0 else f[i][j - limit - 1][0])
278+
) % mod
279+
return sum(f[zero][one]) % mod
280+
```
281+
282+
```java
283+
class Solution {
284+
public int numberOfStableArrays(int zero, int one, int limit) {
285+
final int mod = (int) 1e9 + 7;
286+
long[][][] f = new long[zero + 1][one + 1][2];
287+
for (int i = 1; i <= Math.min(zero, limit); ++i) {
288+
f[i][0][0] = 1;
289+
}
290+
for (int j = 1; j <= Math.min(one, limit); ++j) {
291+
f[0][j][1] = 1;
292+
}
293+
for (int i = 1; i <= zero; ++i) {
294+
for (int j = 1; j <= one; ++j) {
295+
f[i][j][0] = (f[i - 1][j][0] + f[i - 1][j][1]
296+
- (i - limit - 1 < 0 ? 0 : f[i - limit - 1][j][1]) + mod)
297+
% mod;
298+
f[i][j][1] = (f[i][j - 1][0] + f[i][j - 1][1]
299+
- (j - limit - 1 < 0 ? 0 : f[i][j - limit - 1][0]) + mod)
300+
% mod;
301+
}
302+
}
303+
return (int) ((f[zero][one][0] + f[zero][one][1]) % mod);
304+
}
305+
}
306+
```
307+
308+
```cpp
309+
class Solution {
310+
public:
311+
int numberOfStableArrays(int zero, int one, int limit) {
312+
const int mod = 1e9 + 7;
313+
using ll = long long;
314+
ll f[zero + 1][one + 1][2];
315+
memset(f, 0, sizeof(f));
316+
for (int i = 1; i <= min(zero, limit); ++i) {
317+
f[i][0][0] = 1;
318+
}
319+
for (int j = 1; j <= min(one, limit); ++j) {
320+
f[0][j][1] = 1;
321+
}
322+
for (int i = 1; i <= zero; ++i) {
323+
for (int j = 1; j <= one; ++j) {
324+
f[i][j][0] = (f[i - 1][j][0] + f[i - 1][j][1]
325+
- (i - limit - 1 < 0 ? 0 : f[i - limit - 1][j][1]) + mod)
326+
% mod;
327+
f[i][j][1] = (f[i][j - 1][0] + f[i][j - 1][1]
328+
- (j - limit - 1 < 0 ? 0 : f[i][j - limit - 1][0]) + mod)
329+
% mod;
330+
}
331+
}
332+
return (f[zero][one][0] + f[zero][one][1]) % mod;
333+
}
334+
};
335+
```
336+
337+
```go
338+
func numberOfStableArrays(zero int, one int, limit int) int {
339+
const mod int = 1e9 + 7
340+
f := make([][][2]int, zero+1)
341+
for i := range f {
342+
f[i] = make([][2]int, one+1)
343+
}
344+
for i := 1; i <= min(zero, limit); i++ {
345+
f[i][0][0] = 1
346+
}
347+
for j := 1; j <= min(one, limit); j++ {
348+
f[0][j][1] = 1
349+
}
350+
for i := 1; i <= zero; i++ {
351+
for j := 1; j <= one; j++ {
352+
f[i][j][0] = (f[i-1][j][0] + f[i-1][j][1]) % mod
353+
if i-limit-1 >= 0 {
354+
f[i][j][0] = (f[i][j][0] - f[i-limit-1][j][1] + mod) % mod
355+
}
356+
f[i][j][1] = (f[i][j-1][0] + f[i][j-1][1]) % mod
357+
if j-limit-1 >= 0 {
358+
f[i][j][1] = (f[i][j][1] - f[i][j-limit-1][0] + mod) % mod
359+
}
360+
}
361+
}
362+
return (f[zero][one][0] + f[zero][one][1]) % mod
363+
}
93364
```
94365

95366
<!-- tabs:end -->

0 commit comments

Comments
 (0)