Skip to content

Commit fec61fd

Browse files
committed
feat: add solutions to lc problem: No.1140
No.1140.Stone Game II
1 parent cf791fa commit fec61fd

File tree

8 files changed

+156
-71
lines changed

8 files changed

+156
-71
lines changed

solution/1100-1199/1140.Stone Game II/README.md

Lines changed: 58 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,20 @@
4848

4949
**方法一:前缀和 + 记忆化搜索**
5050

51-
我们先预处理出前缀和数组 $s$,其中 $s[i]$ 表示数组 `piles` 的前 $i$ 个元素的和。
51+
由于玩家每次可以拿走前 $X$ 堆的所有石子,也就是说能拿走一个区间的石子,因此,我们可以先预处理出一个长度为 $n+1$ 的前缀和数组 $s$,其中 $s[i]$ 表示数组 `piles` 的前 $i$ 个元素的和。
5252

53-
然后我们设计一个函数 $dfs(i, m)$,表示当前轮到的人可以从数组 `piles` 的下标 $i$ 开始拿,且当前的 $M$ 为 $m$ 时,当前轮到的人能够拿到的最大石子数。那么答案就是 $dfs(0, 1)$。
53+
然后我们设计一个函数 $dfs(i, m)$,表示当前轮到的人可以从数组 `piles` 的下标 $i$ 开始拿,且当前的 $M$ 为 $m$ 时,当前轮到的人能够拿到的最大石子数。初始时爱丽丝从下标 $0$ 开始,且 $M=1$,所以我们需要求的答案为 $dfs(0, 1)$。
5454

5555
函数 $dfs(i, m)$ 的计算过程如下:
5656

57-
- 如果当前轮到的人可以拿走剩下的所有石子,那么当前轮到的人就可以拿走剩下的所有石子,因此当前轮到的人能够拿到的最大石子数为 $s[n] - s[i]$,其中 $n$ 为数组 `piles` 的长度。
58-
- 否则,当前轮到的人可以拿走剩下的前 $x$ 堆的所有石子,其中 $1 \leq x \leq 2m$,那么当前轮到的人能够拿到的最大石子数为 $s[n] - s[i] - dfs(i + x, max(m, x))$。我们需要遍历所有的 $x$,取其中的最大值。
59-
60-
最后,我们返回 $dfs(0, 1)$ 即可。
57+
- 如果当前轮到的人可以拿走剩下的所有石子,能够拿到的最大石子数为 $s[n] - s[i]$;
58+
- 否则,当前轮到的人可以拿走剩下的前 $x$ 堆的所有石子,其中 $1 \leq x \leq 2m$,能够拿到的最大石子数为 $s[n] - s[i] - dfs(i + x, max(m, x))$。也即是说,当前轮的人能够拿到的石子数为当前剩下的所有石子数减去下一轮对手能够拿到的石子数。我们需要枚举所有的 $x$,取其中的最大值作为函数 $dfs(i, m)$ 的返回值。
6159

6260
为了避免重复计算,我们可以使用记忆化搜索。
6361

64-
时间复杂度为 $O(n^2)$,空间复杂度为 $O(n^2)$。其中 $n$ 为数组 `piles` 的长度。
62+
最后,我们返回将 $dfs(0, 1)$ 作为答案返回即可。
63+
64+
时间复杂度为 $O(n^3)$,空间复杂度为 $O(n^2)$。其中 $n$ 为数组 `piles` 的长度。
6565

6666
<!-- tabs:start -->
6767

@@ -75,15 +75,13 @@ class Solution:
7575
@cache
7676
def dfs(i, m):
7777
if m * 2 >= n - i:
78-
return s[-1] - s[i]
79-
res = 0
80-
for x in range(1, m << 1 | 1):
81-
t = s[-1] - s[i] - dfs(i + x, max(m, x))
82-
res = max(res, t)
83-
return res
78+
return s[n] - s[i]
79+
return max(
80+
s[n] - s[i] - dfs(i + x, max(m, x)) for x in range(1, m << 1 | 1)
81+
)
8482

85-
s = list(accumulate(piles, initial=0))
8683
n = len(piles)
84+
s = list(accumulate(piles, initial=0))
8785
return dfs(0, 1)
8886
```
8987

@@ -114,12 +112,11 @@ class Solution {
114112
if (f[i][m] != null) {
115113
return f[i][m];
116114
}
117-
f[i][m] = 0;
115+
int res = 0;
118116
for (int x = 1; x <= m * 2; ++x) {
119-
int t = s[n] - s[i] - dfs(i + x, Math.max(m, x));
120-
f[i][m] = Math.max(f[i][m], t);
117+
res = Math.max(res, s[n] - s[i] - dfs(i + x, Math.max(m, x)));
121118
}
122-
return f[i][m];
119+
return f[i][m] = res;
123120
}
124121
}
125122
```
@@ -133,17 +130,23 @@ public:
133130
int n = piles.size();
134131
int s[n + 1];
135132
s[0] = 0;
136-
for (int i = 0; i < n; ++i) s[i + 1] = s[i] + piles[i];
133+
for (int i = 0; i < n; ++i) {
134+
s[i + 1] = s[i] + piles[i];
135+
}
137136
int f[n][n + 1];
138137
memset(f, 0, sizeof f);
139138
function<int(int, int)> dfs = [&](int i, int m) -> int {
140-
if (m * 2 >= n - i) return s[n] - s[i];
141-
if (f[i][m]) return f[i][m];
139+
if (m * 2 >= n - i) {
140+
return s[n] - s[i];
141+
}
142+
if (f[i][m]) {
143+
return f[i][m];
144+
}
145+
int res = 0;
142146
for (int x = 1; x <= m << 1; ++x) {
143-
int t = s[n] - s[i] - dfs(i + x, max(x, m));
144-
f[i][m] = max(f[i][m], t);
147+
res = max(res, s[n] - s[i] - dfs(i + x, max(x, m)));
145148
}
146-
return f[i][m];
149+
return f[i][m] = res;
147150
};
148151
return dfs(0, 1);
149152
}
@@ -157,8 +160,8 @@ func stoneGameII(piles []int) int {
157160
n := len(piles)
158161
s := make([]int, n+1)
159162
f := make([][]int, n+1)
160-
for i, v := range piles {
161-
s[i+1] = s[i] + v
163+
for i, x := range piles {
164+
s[i+1] = s[i] + x
162165
f[i] = make([]int, n+1)
163166
}
164167
var dfs func(i, m int) int
@@ -169,9 +172,9 @@ func stoneGameII(piles []int) int {
169172
if f[i][m] > 0 {
170173
return f[i][m]
171174
}
175+
f[i][m] = 0
172176
for x := 1; x <= m<<1; x++ {
173-
t := s[n] - s[i] - dfs(i+x, max(m, x))
174-
f[i][m] = max(f[i][m], t)
177+
f[i][m] = max(f[i][m], s[n]-s[i]-dfs(i+x, max(m, x)))
175178
}
176179
return f[i][m]
177180
}
@@ -186,6 +189,33 @@ func max(a, b int) int {
186189
}
187190
```
188191

192+
### **TypeScript**
193+
194+
```ts
195+
function stoneGameII(piles: number[]): number {
196+
const n = piles.length;
197+
const f = Array.from({ length: n }, _ => new Array(n + 1).fill(0));
198+
const s = new Array(n + 1).fill(0);
199+
for (let i = 0; i < n; ++i) {
200+
s[i + 1] = s[i] + piles[i];
201+
}
202+
const dfs = (i: number, m: number) => {
203+
if (m * 2 >= n - i) {
204+
return s[n] - s[i];
205+
}
206+
if (f[i][m]) {
207+
return f[i][m];
208+
}
209+
let res = 0;
210+
for (let x = 1; x <= m * 2; ++x) {
211+
res = Math.max(res, s[n] - s[i] - dfs(i + x, Math.max(m, x)));
212+
}
213+
return (f[i][m] = res);
214+
};
215+
return dfs(0, 1);
216+
}
217+
```
218+
189219
### **...**
190220

191221
```

solution/1100-1199/1140.Stone Game II/README_EN.md

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,13 @@ class Solution:
5050
@cache
5151
def dfs(i, m):
5252
if m * 2 >= n - i:
53-
return s[-1] - s[i]
54-
res = 0
55-
for x in range(1, m << 1 | 1):
56-
t = s[-1] - s[i] - dfs(i + x, max(m, x))
57-
res = max(res, t)
58-
return res
53+
return s[n] - s[i]
54+
return max(
55+
s[n] - s[i] - dfs(i + x, max(m, x)) for x in range(1, m << 1 | 1)
56+
)
5957

60-
s = list(accumulate(piles, initial=0))
6158
n = len(piles)
59+
s = list(accumulate(piles, initial=0))
6260
return dfs(0, 1)
6361
```
6462

@@ -87,12 +85,11 @@ class Solution {
8785
if (f[i][m] != null) {
8886
return f[i][m];
8987
}
90-
f[i][m] = 0;
88+
int res = 0;
9189
for (int x = 1; x <= m * 2; ++x) {
92-
int t = s[n] - s[i] - dfs(i + x, Math.max(m, x));
93-
f[i][m] = Math.max(f[i][m], t);
90+
res = Math.max(res, s[n] - s[i] - dfs(i + x, Math.max(m, x)));
9491
}
95-
return f[i][m];
92+
return f[i][m] = res;
9693
}
9794
}
9895
```
@@ -106,17 +103,23 @@ public:
106103
int n = piles.size();
107104
int s[n + 1];
108105
s[0] = 0;
109-
for (int i = 0; i < n; ++i) s[i + 1] = s[i] + piles[i];
106+
for (int i = 0; i < n; ++i) {
107+
s[i + 1] = s[i] + piles[i];
108+
}
110109
int f[n][n + 1];
111110
memset(f, 0, sizeof f);
112111
function<int(int, int)> dfs = [&](int i, int m) -> int {
113-
if (m * 2 >= n - i) return s[n] - s[i];
114-
if (f[i][m]) return f[i][m];
112+
if (m * 2 >= n - i) {
113+
return s[n] - s[i];
114+
}
115+
if (f[i][m]) {
116+
return f[i][m];
117+
}
118+
int res = 0;
115119
for (int x = 1; x <= m << 1; ++x) {
116-
int t = s[n] - s[i] - dfs(i + x, max(x, m));
117-
f[i][m] = max(f[i][m], t);
120+
res = max(res, s[n] - s[i] - dfs(i + x, max(x, m)));
118121
}
119-
return f[i][m];
122+
return f[i][m] = res;
120123
};
121124
return dfs(0, 1);
122125
}
@@ -130,8 +133,8 @@ func stoneGameII(piles []int) int {
130133
n := len(piles)
131134
s := make([]int, n+1)
132135
f := make([][]int, n+1)
133-
for i, v := range piles {
134-
s[i+1] = s[i] + v
136+
for i, x := range piles {
137+
s[i+1] = s[i] + x
135138
f[i] = make([]int, n+1)
136139
}
137140
var dfs func(i, m int) int
@@ -142,9 +145,9 @@ func stoneGameII(piles []int) int {
142145
if f[i][m] > 0 {
143146
return f[i][m]
144147
}
148+
f[i][m] = 0
145149
for x := 1; x <= m<<1; x++ {
146-
t := s[n] - s[i] - dfs(i+x, max(m, x))
147-
f[i][m] = max(f[i][m], t)
150+
f[i][m] = max(f[i][m], s[n]-s[i]-dfs(i+x, max(m, x)))
148151
}
149152
return f[i][m]
150153
}
@@ -159,6 +162,33 @@ func max(a, b int) int {
159162
}
160163
```
161164

165+
### **TypeScript**
166+
167+
```ts
168+
function stoneGameII(piles: number[]): number {
169+
const n = piles.length;
170+
const f = Array.from({ length: n }, _ => new Array(n + 1).fill(0));
171+
const s = new Array(n + 1).fill(0);
172+
for (let i = 0; i < n; ++i) {
173+
s[i + 1] = s[i] + piles[i];
174+
}
175+
const dfs = (i: number, m: number) => {
176+
if (m * 2 >= n - i) {
177+
return s[n] - s[i];
178+
}
179+
if (f[i][m]) {
180+
return f[i][m];
181+
}
182+
let res = 0;
183+
for (let x = 1; x <= m * 2; ++x) {
184+
res = Math.max(res, s[n] - s[i] - dfs(i + x, Math.max(m, x)));
185+
}
186+
return (f[i][m] = res);
187+
};
188+
return dfs(0, 1);
189+
}
190+
```
191+
162192
### **...**
163193

164194
```

solution/1100-1199/1140.Stone Game II/Solution.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,23 @@ class Solution {
44
int n = piles.size();
55
int s[n + 1];
66
s[0] = 0;
7-
for (int i = 0; i < n; ++i) s[i + 1] = s[i] + piles[i];
7+
for (int i = 0; i < n; ++i) {
8+
s[i + 1] = s[i] + piles[i];
9+
}
810
int f[n][n + 1];
911
memset(f, 0, sizeof f);
1012
function<int(int, int)> dfs = [&](int i, int m) -> int {
11-
if (m * 2 >= n - i) return s[n] - s[i];
12-
if (f[i][m]) return f[i][m];
13+
if (m * 2 >= n - i) {
14+
return s[n] - s[i];
15+
}
16+
if (f[i][m]) {
17+
return f[i][m];
18+
}
19+
int res = 0;
1320
for (int x = 1; x <= m << 1; ++x) {
14-
int t = s[n] - s[i] - dfs(i + x, max(x, m));
15-
f[i][m] = max(f[i][m], t);
21+
res = max(res, s[n] - s[i] - dfs(i + x, max(x, m)));
1622
}
17-
return f[i][m];
23+
return f[i][m] = res;
1824
};
1925
return dfs(0, 1);
2026
}

solution/1100-1199/1140.Stone Game II/Solution.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ func stoneGameII(piles []int) int {
22
n := len(piles)
33
s := make([]int, n+1)
44
f := make([][]int, n+1)
5-
for i, v := range piles {
6-
s[i+1] = s[i] + v
5+
for i, x := range piles {
6+
s[i+1] = s[i] + x
77
f[i] = make([]int, n+1)
88
}
99
var dfs func(i, m int) int
@@ -14,9 +14,9 @@ func stoneGameII(piles []int) int {
1414
if f[i][m] > 0 {
1515
return f[i][m]
1616
}
17+
f[i][m] = 0
1718
for x := 1; x <= m<<1; x++ {
18-
t := s[n] - s[i] - dfs(i+x, max(m, x))
19-
f[i][m] = max(f[i][m], t)
19+
f[i][m] = max(f[i][m], s[n]-s[i]-dfs(i+x, max(m, x)))
2020
}
2121
return f[i][m]
2222
}

solution/1100-1199/1140.Stone Game II/Solution.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,10 @@ private int dfs(int i, int m) {
2020
if (f[i][m] != null) {
2121
return f[i][m];
2222
}
23-
f[i][m] = 0;
23+
int res = 0;
2424
for (int x = 1; x <= m * 2; ++x) {
25-
int t = s[n] - s[i] - dfs(i + x, Math.max(m, x));
26-
f[i][m] = Math.max(f[i][m], t);
25+
res = Math.max(res, s[n] - s[i] - dfs(i + x, Math.max(m, x)));
2726
}
28-
return f[i][m];
27+
return f[i][m] = res;
2928
}
3029
}

solution/1100-1199/1140.Stone Game II/Solution.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@ def stoneGameII(self, piles: List[int]) -> int:
33
@cache
44
def dfs(i, m):
55
if m * 2 >= n - i:
6-
return s[-1] - s[i]
7-
res = 0
8-
for x in range(1, m << 1 | 1):
9-
t = s[-1] - s[i] - dfs(i + x, max(m, x))
10-
res = max(res, t)
11-
return res
6+
return s[n] - s[i]
7+
return max(
8+
s[n] - s[i] - dfs(i + x, max(m, x)) for x in range(1, m << 1 | 1)
9+
)
1210

13-
s = list(accumulate(piles, initial=0))
1411
n = len(piles)
12+
s = list(accumulate(piles, initial=0))
1513
return dfs(0, 1)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
function stoneGameII(piles: number[]): number {
2+
const n = piles.length;
3+
const f = Array.from({ length: n }, _ => new Array(n + 1).fill(0));
4+
const s = new Array(n + 1).fill(0);
5+
for (let i = 0; i < n; ++i) {
6+
s[i + 1] = s[i] + piles[i];
7+
}
8+
const dfs = (i: number, m: number) => {
9+
if (m * 2 >= n - i) {
10+
return s[n] - s[i];
11+
}
12+
if (f[i][m]) {
13+
return f[i][m];
14+
}
15+
let res = 0;
16+
for (let x = 1; x <= m * 2; ++x) {
17+
res = Math.max(res, s[n] - s[i] - dfs(i + x, Math.max(m, x)));
18+
}
19+
return (f[i][m] = res);
20+
};
21+
return dfs(0, 1);
22+
}

solution/1300-1399/1324.Print Words Vertically/Solution.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ def printVertically(self, s: str) -> List[str]:
88
while t[-1] == ' ':
99
t.pop()
1010
ans.append(''.join(t))
11-
return ans
11+
return ans

0 commit comments

Comments
 (0)