Skip to content

Commit 5a9b264

Browse files
committed
feat: add solutions to lc problem: No.1406
No.1406.Stone Game III
1 parent 82451a5 commit 5a9b264

File tree

6 files changed

+387
-2
lines changed

6 files changed

+387
-2
lines changed

solution/1400-1499/1406.Stone Game III/README.md

+140-1
Original file line numberDiff line numberDiff line change
@@ -64,22 +64,161 @@
6464

6565
<!-- 这里可写通用的实现逻辑 -->
6666

67+
**方法一:前缀和 + 记忆化搜索**
68+
69+
我们先预处理出数组 $stoneValue$ 的前缀和数组 $s$,其中 $s[i]$ 表示 $stoneValue$ 数组前 $i$ 个元素之和。
70+
71+
接下来,我们设计一个函数 $dfs(i)$,表示当前玩家从 $stoneValue$ 数组下标 $i$ 开始拿石子时,能够获得的最大分数。如果当前玩家拿走了 $stoneValue$ 数组下标 $i$ 开始的 $j$ 堆石子,那么下一个玩家能够获得的最大分数为 $dfs(i + j)$,为了使当前玩家获得的分数最大化,我们需要让 $dfs(i + j)$ 最小化,即 $dfs(i) = s[n] - s[i] - min(dfs(i + j))$,其中 $s[n]$ 表示 $stoneValue$ 数组所有元素之和。
72+
73+
最后,玩家 $Alice$ 的分数为 $dfs(0)$,玩家 $Bob$ 的分数为 $s[n] - dfs(0)$,如果 $Alice$ 的分数大于 $Bob$ 的分数,那么 $Alice$ 获胜;如果 $Alice$ 的分数小于 $Bob$ 的分数,那么 $Bob$ 获胜;如果 $Alice$ 的分数等于 $Bob$ 的分数,那么平局。
74+
75+
过程中,我们可以使用记忆化搜索,避免重复计算。
76+
77+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $stoneValue$ 的长度。
78+
6779
<!-- tabs:start -->
6880

6981
### **Python3**
7082

7183
<!-- 这里可写当前语言的特殊实现逻辑 -->
7284

7385
```python
74-
86+
class Solution:
87+
def stoneGameIII(self, stoneValue: List[int]) -> str:
88+
@cache
89+
def dfs(i: int) -> int:
90+
if i >= len(stoneValue):
91+
return 0
92+
t = min(dfs(i + j) for j in range(1, 4))
93+
return s[-1] - s[i] - t
94+
95+
s = list(accumulate(stoneValue, initial=0))
96+
a = dfs(0)
97+
b = s[-1] - a
98+
if a == b:
99+
return 'Tie'
100+
return 'Alice' if a > b else 'Bob'
75101
```
76102

77103
### **Java**
78104

79105
<!-- 这里可写当前语言的特殊实现逻辑 -->
80106

81107
```java
108+
class Solution {
109+
private int n;
110+
private int[] s;
111+
private Integer[] f;
112+
113+
public String stoneGameIII(int[] stoneValue) {
114+
n = stoneValue.length;
115+
s = new int[n + 1];
116+
f = new Integer[n];
117+
for (int i = 1; i <= n; ++i) {
118+
s[i] = s[i - 1] + stoneValue[i - 1];
119+
}
120+
int a = dfs(0);
121+
int b = s[n] - a;
122+
return a == b ? "Tie" : a > b ? "Alice" : "Bob";
123+
}
124+
125+
private int dfs(int i) {
126+
if (i >= n) {
127+
return 0;
128+
}
129+
if (f[i] != null) {
130+
return f[i];
131+
}
132+
int t = 1 << 30;
133+
for (int j = 1; j < 4; ++j) {
134+
t = Math.min(t, dfs(i + j));
135+
}
136+
f[i] = s[n] - s[i] - t;
137+
return f[i];
138+
}
139+
}
140+
```
141+
142+
### **C++**
143+
144+
```cpp
145+
class Solution {
146+
public:
147+
string stoneGameIII(vector<int>& stoneValue) {
148+
int n = stoneValue.size();
149+
int s[n + 1];
150+
s[0] = 0;
151+
for (int i = 1; i <= n; ++i) {
152+
s[i] = s[i - 1] + stoneValue[i - 1];
153+
}
154+
int f[n];
155+
memset(f, 0x3f, sizeof(f));
156+
function<int(int)> dfs = [&](int i) -> int {
157+
if (i >= n) {
158+
return 0;
159+
}
160+
if (f[i] != 0x3f3f3f3f) {
161+
return f[i];
162+
}
163+
int t = 1 << 30;
164+
for (int j = 1; j < 4; ++j) {
165+
t = min(t, dfs(i + j));
166+
}
167+
return f[i] = s[n] - s[i] - t;
168+
};
169+
int a = dfs(0);
170+
int b = s[n] - a;
171+
return a == b ? "Tie" : (a > b ? "Alice" : "Bob");
172+
}
173+
};
174+
```
82175
176+
### **Go**
177+
178+
```go
179+
func stoneGameIII(stoneValue []int) string {
180+
n := len(stoneValue)
181+
s := make([]int, n+1)
182+
for i, x := range stoneValue {
183+
s[i+1] = s[i] + x
184+
}
185+
const inf = 1 << 30
186+
f := make([]int, n)
187+
for i := range f {
188+
f[i] = inf
189+
}
190+
var dfs func(int) int
191+
dfs = func(i int) int {
192+
if i >= n {
193+
return 0
194+
}
195+
if f[i] != inf {
196+
return f[i]
197+
}
198+
t := inf
199+
for j := 1; j <= 3; j++ {
200+
t = min(t, dfs(i+j))
201+
}
202+
f[i] = s[n] - s[i] - t
203+
return f[i]
204+
}
205+
a := dfs(0)
206+
b := s[n] - a
207+
if a == b {
208+
return "Tie"
209+
}
210+
if a > b {
211+
return "Alice"
212+
}
213+
return "Bob"
214+
}
215+
216+
func min(a, b int) int {
217+
if a < b {
218+
return a
219+
}
220+
return b
221+
}
83222
```
84223

85224
### **...**

solution/1400-1499/1406.Stone Game III/README_EN.md

+128-1
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,140 @@ Remember that both play optimally so here Alice will choose the scenario that ma
5959
### **Python3**
6060

6161
```python
62-
62+
class Solution:
63+
def stoneGameIII(self, stoneValue: List[int]) -> str:
64+
@cache
65+
def dfs(i: int) -> int:
66+
if i >= len(stoneValue):
67+
return 0
68+
t = min(dfs(i + j) for j in range(1, 4))
69+
return s[-1] - s[i] - t
70+
71+
s = list(accumulate(stoneValue, initial=0))
72+
a = dfs(0)
73+
b = s[-1] - a
74+
if a == b:
75+
return 'Tie'
76+
return 'Alice' if a > b else 'Bob'
6377
```
6478

6579
### **Java**
6680

6781
```java
82+
class Solution {
83+
private int n;
84+
private int[] s;
85+
private Integer[] f;
86+
87+
public String stoneGameIII(int[] stoneValue) {
88+
n = stoneValue.length;
89+
s = new int[n + 1];
90+
f = new Integer[n];
91+
for (int i = 1; i <= n; ++i) {
92+
s[i] = s[i - 1] + stoneValue[i - 1];
93+
}
94+
int a = dfs(0);
95+
int b = s[n] - a;
96+
return a == b ? "Tie" : a > b ? "Alice" : "Bob";
97+
}
98+
99+
private int dfs(int i) {
100+
if (i >= n) {
101+
return 0;
102+
}
103+
if (f[i] != null) {
104+
return f[i];
105+
}
106+
int t = 1 << 30;
107+
for (int j = 1; j < 4; ++j) {
108+
t = Math.min(t, dfs(i + j));
109+
}
110+
f[i] = s[n] - s[i] - t;
111+
return f[i];
112+
}
113+
}
114+
```
115+
116+
### **C++**
117+
118+
```cpp
119+
class Solution {
120+
public:
121+
string stoneGameIII(vector<int>& stoneValue) {
122+
int n = stoneValue.size();
123+
int s[n + 1];
124+
s[0] = 0;
125+
for (int i = 1; i <= n; ++i) {
126+
s[i] = s[i - 1] + stoneValue[i - 1];
127+
}
128+
int f[n];
129+
memset(f, 0x3f, sizeof(f));
130+
function<int(int)> dfs = [&](int i) -> int {
131+
if (i >= n) {
132+
return 0;
133+
}
134+
if (f[i] != 0x3f3f3f3f) {
135+
return f[i];
136+
}
137+
int t = 1 << 30;
138+
for (int j = 1; j < 4; ++j) {
139+
t = min(t, dfs(i + j));
140+
}
141+
return f[i] = s[n] - s[i] - t;
142+
};
143+
int a = dfs(0);
144+
int b = s[n] - a;
145+
return a == b ? "Tie" : (a > b ? "Alice" : "Bob");
146+
}
147+
};
148+
```
68149
150+
### **Go**
151+
152+
```go
153+
func stoneGameIII(stoneValue []int) string {
154+
n := len(stoneValue)
155+
s := make([]int, n+1)
156+
for i, x := range stoneValue {
157+
s[i+1] = s[i] + x
158+
}
159+
const inf = 1 << 30
160+
f := make([]int, n)
161+
for i := range f {
162+
f[i] = inf
163+
}
164+
var dfs func(int) int
165+
dfs = func(i int) int {
166+
if i >= n {
167+
return 0
168+
}
169+
if f[i] != inf {
170+
return f[i]
171+
}
172+
t := inf
173+
for j := 1; j <= 3; j++ {
174+
t = min(t, dfs(i+j))
175+
}
176+
f[i] = s[n] - s[i] - t
177+
return f[i]
178+
}
179+
a := dfs(0)
180+
b := s[n] - a
181+
if a == b {
182+
return "Tie"
183+
}
184+
if a > b {
185+
return "Alice"
186+
}
187+
return "Bob"
188+
}
189+
190+
func min(a, b int) int {
191+
if a < b {
192+
return a
193+
}
194+
return b
195+
}
69196
```
70197

71198
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
class Solution {
2+
public:
3+
string stoneGameIII(vector<int>& stoneValue) {
4+
int n = stoneValue.size();
5+
int s[n + 1];
6+
s[0] = 0;
7+
for (int i = 1; i <= n; ++i) {
8+
s[i] = s[i - 1] + stoneValue[i - 1];
9+
}
10+
int f[n];
11+
memset(f, 0x3f, sizeof(f));
12+
function<int(int)> dfs = [&](int i) -> int {
13+
if (i >= n) {
14+
return 0;
15+
}
16+
if (f[i] != 0x3f3f3f3f) {
17+
return f[i];
18+
}
19+
int t = 1 << 30;
20+
for (int j = 1; j < 4; ++j) {
21+
t = min(t, dfs(i + j));
22+
}
23+
return f[i] = s[n] - s[i] - t;
24+
};
25+
int a = dfs(0);
26+
int b = s[n] - a;
27+
return a == b ? "Tie" : (a > b ? "Alice" : "Bob");
28+
}
29+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
func stoneGameIII(stoneValue []int) string {
2+
n := len(stoneValue)
3+
s := make([]int, n+1)
4+
for i, x := range stoneValue {
5+
s[i+1] = s[i] + x
6+
}
7+
const inf = 1 << 30
8+
f := make([]int, n)
9+
for i := range f {
10+
f[i] = inf
11+
}
12+
var dfs func(int) int
13+
dfs = func(i int) int {
14+
if i >= n {
15+
return 0
16+
}
17+
if f[i] != inf {
18+
return f[i]
19+
}
20+
t := inf
21+
for j := 1; j <= 3; j++ {
22+
t = min(t, dfs(i+j))
23+
}
24+
f[i] = s[n] - s[i] - t
25+
return f[i]
26+
}
27+
a := dfs(0)
28+
b := s[n] - a
29+
if a == b {
30+
return "Tie"
31+
}
32+
if a > b {
33+
return "Alice"
34+
}
35+
return "Bob"
36+
}
37+
38+
func min(a, b int) int {
39+
if a < b {
40+
return a
41+
}
42+
return b
43+
}

0 commit comments

Comments
 (0)