Skip to content

Commit 1403957

Browse files
authored
feat: add solutions to lc problem: No.3320 (#3640)
No.3320.Count The Number of Winning Sequences
1 parent 5d8c2f9 commit 1403957

File tree

6 files changed

+539
-10
lines changed

6 files changed

+539
-10
lines changed

solution/3300-3399/3320.Count The Number of Winning Sequences/README.md

+184-5
Original file line numberDiff line numberDiff line change
@@ -79,32 +79,211 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3320.Co
7979

8080
<!-- solution:start -->
8181

82-
### 方法一
82+
### 方法一:记忆化搜索
83+
84+
我们设计一个函数 $\textit{dfs}(i, j, k)$,其中 $i$ 表示从字符串 $s$ 的第 $i$ 个字符开始,目前 $\textit{Alice}$ 与 $\textit{Bob}$ 的分数差为 $j$,并且 $\textit{Bob}$ 上一次召唤的生物是 $k$,一共有多少种 $\textit{Bob}$ 的出招序列可以战胜 $\textit{Alice}$。
85+
86+
那么答案就是 $\textit{dfs}(0, 0, -1)$。其中 $-1$ 表示 $\textit{Bob}$ 还没有召唤过生物。在除了 $\textit{Python}$ 之外的语言中,由于分数差可能为负数,我们可以将分数差加上 $n$,这样就可以保证分数差为非负数。
87+
88+
函数 $\textit{dfs}(i, j, k)$ 的计算过程如下:
89+
90+
- 如果 $n - i \leq j$,那么剩余的回合数不足以使 $\textit{Bob}$ 的分数超过 $\textit{Alice}$ 的分数,此时返回 $0$。
91+
- 如果 $i \geq n$,那么所有回合已经结束,如果 $\textit{Bob}$ 的分数小于 $0$,那么返回 $1$,否则返回 $0$。
92+
- 否则,我们枚举 $\textit{Bob}$ 这一回合召唤的生物,如果这一回合召唤的生物与上一回合召唤的生物相同,那么这一回合 $\textit{Bob}$ 无法获胜,直接跳过。否则,我们递归计算 $\textit{dfs}(i + 1, j + \textit{calc}(d[s[i]], l), l)$,其中 $\textit{calc}(x, y)$ 表示 $x$ 与 $y$ 之间的胜负关系,而 $d$ 是一个映射,将字符映射到 $\textit{012}$。我们将所有的结果相加并对 $10^9 + 7$ 取模。
93+
94+
时间复杂度 $O(n^2 \times k^2)$,其中 $n$ 是字符串 $s$ 的长度,而 $k$ 表示字符集的大小。空间复杂度 $O(n^2 \times k)$。
8395

8496
<!-- tabs:start -->
8597

8698
#### Python3
8799

88100
```python
89-
101+
class Solution:
102+
def countWinningSequences(self, s: str) -> int:
103+
def calc(x: int, y: int) -> int:
104+
if x == y:
105+
return 0
106+
if x < y:
107+
return 1 if x == 0 and y == 2 else -1
108+
return -1 if x == 2 and y == 0 else 1
109+
110+
@cache
111+
def dfs(i: int, j: int, k: int) -> int:
112+
if len(s) - i <= j:
113+
return 0
114+
if i >= len(s):
115+
return int(j < 0)
116+
res = 0
117+
for l in range(3):
118+
if l == k:
119+
continue
120+
res = (res + dfs(i + 1, j + calc(d[s[i]], l), l)) % mod
121+
return res
122+
123+
mod = 10**9 + 7
124+
d = {"F": 0, "W": 1, "E": 2}
125+
ans = dfs(0, 0, -1)
126+
dfs.cache_clear()
127+
return ans
90128
```
91129

92130
#### Java
93131

94132
```java
95-
133+
class Solution {
134+
private int n;
135+
private char[] s;
136+
private int[] d = new int[26];
137+
private Integer[][][] f;
138+
private final int mod = (int) 1e9 + 7;
139+
140+
public int countWinningSequences(String s) {
141+
d['W' - 'A'] = 1;
142+
d['E' - 'A'] = 2;
143+
this.s = s.toCharArray();
144+
n = this.s.length;
145+
f = new Integer[n][n + n + 1][4];
146+
return dfs(0, n, 3);
147+
}
148+
149+
private int dfs(int i, int j, int k) {
150+
if (n - i <= j - n) {
151+
return 0;
152+
}
153+
if (i >= n) {
154+
return j - n < 0 ? 1 : 0;
155+
}
156+
if (f[i][j][k] != null) {
157+
return f[i][j][k];
158+
}
159+
160+
int ans = 0;
161+
for (int l = 0; l < 3; ++l) {
162+
if (l == k) {
163+
continue;
164+
}
165+
ans = (ans + dfs(i + 1, j + calc(d[s[i] - 'A'], l), l)) % mod;
166+
}
167+
return f[i][j][k] = ans;
168+
}
169+
170+
private int calc(int x, int y) {
171+
if (x == y) {
172+
return 0;
173+
}
174+
if (x < y) {
175+
return x == 0 && y == 2 ? 1 : -1;
176+
}
177+
return x == 2 && y == 0 ? -1 : 1;
178+
}
179+
}
96180
```
97181

98182
#### C++
99183

100184
```cpp
101-
185+
class Solution {
186+
public:
187+
int countWinningSequences(string s) {
188+
int n = s.size();
189+
int d[26]{};
190+
d['W' - 'A'] = 1;
191+
d['E' - 'A'] = 2;
192+
int f[n][n + n + 1][4];
193+
memset(f, -1, sizeof(f));
194+
auto calc = [](int x, int y) -> int {
195+
if (x == y) {
196+
return 0;
197+
}
198+
if (x < y) {
199+
return x == 0 && y == 2 ? 1 : -1;
200+
}
201+
return x == 2 && y == 0 ? -1 : 1;
202+
};
203+
const int mod = 1e9 + 7;
204+
auto dfs = [&](auto&& dfs, int i, int j, int k) -> int {
205+
if (n - i <= j - n) {
206+
return 0;
207+
}
208+
if (i >= n) {
209+
return j - n < 0 ? 1 : 0;
210+
}
211+
if (f[i][j][k] != -1) {
212+
return f[i][j][k];
213+
}
214+
int ans = 0;
215+
for (int l = 0; l < 3; ++l) {
216+
if (l == k) {
217+
continue;
218+
}
219+
ans = (ans + dfs(dfs, i + 1, j + calc(d[s[i] - 'A'], l), l)) % mod;
220+
}
221+
return f[i][j][k] = ans;
222+
};
223+
return dfs(dfs, 0, n, 3);
224+
}
225+
};
102226
```
103227
104228
#### Go
105229
106230
```go
107-
231+
func countWinningSequences(s string) int {
232+
const mod int = 1e9 + 7
233+
d := [26]int{}
234+
d['W'-'A'] = 1
235+
d['E'-'A'] = 2
236+
n := len(s)
237+
f := make([][][4]int, n)
238+
for i := range f {
239+
f[i] = make([][4]int, n+n+1)
240+
for j := range f[i] {
241+
for k := range f[i][j] {
242+
f[i][j][k] = -1
243+
}
244+
}
245+
}
246+
calc := func(x, y int) int {
247+
if x == y {
248+
return 0
249+
}
250+
if x < y {
251+
if x == 0 && y == 2 {
252+
return 1
253+
}
254+
return -1
255+
}
256+
if x == 2 && y == 0 {
257+
return -1
258+
}
259+
return 1
260+
}
261+
var dfs func(int, int, int) int
262+
dfs = func(i, j, k int) int {
263+
if n-i <= j-n {
264+
return 0
265+
}
266+
if i >= n {
267+
if j-n < 0 {
268+
return 1
269+
}
270+
return 0
271+
}
272+
if v := f[i][j][k]; v != -1 {
273+
return v
274+
}
275+
ans := 0
276+
for l := 0; l < 3; l++ {
277+
if l == k {
278+
continue
279+
}
280+
ans = (ans + dfs(i+1, j+calc(d[s[i]-'A'], l), l)) % mod
281+
}
282+
f[i][j][k] = ans
283+
return ans
284+
}
285+
return dfs(0, n, 3)
286+
}
108287
```
109288

110289
<!-- tabs:end -->

0 commit comments

Comments
 (0)