Skip to content

Commit 5d31bb9

Browse files
committed
feat: add solutions to lc problem: No.1510
No.1510.Stone Game IV
1 parent c5ff754 commit 5d31bb9

File tree

10 files changed

+429
-4
lines changed

10 files changed

+429
-4
lines changed

solution/1400-1499/1492.The kth Factor of n/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666

6767
我们可以发现,如果 $n$ 有一个因子 $x$,那么 $n$ 一定也有一个因子 $n/x$。
6868

69-
因此,我们先需要枚举 $[1,2,...\left \lfloor \sqrt{n} \right \rfloor ]$,找到所有能整除 $n$ 的数,如果找到第 $k$ 个因子,那么直接返回即可。如果没有找到第 $k$ 个因子,那么我们再倒序枚举 $[\left \lfloor \sqrt{n} \right \rfloor ,..1]$,找到第 $k$ 个因子即可。
69+
因此,我们先需要枚举 $[1,2,...\left \lfloor \sqrt{n} \right \rfloor]$,找到所有能整除 $n$ 的数,如果找到第 $k$ 个因子,那么直接返回即可。如果没有找到第 $k$ 个因子,那么我们再倒序枚举 $[\left \lfloor \sqrt{n} \right \rfloor ,..1]$,找到第 $k$ 个因子即可。
7070

7171
时间复杂度 $O(\sqrt{n})$。
7272

solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class Solution:
7474
for i in range(n - 2, -1, -1):
7575
if nums[i + 1] == 1:
7676
right[i] = right[i + 1] + 1
77-
return max(left[i] + right[i] for i in range(n))
77+
return max(a + b for a, b in zip(left, right))
7878
```
7979

8080
### **Java**

solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/README_EN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class Solution:
5959
for i in range(n - 2, -1, -1):
6060
if nums[i + 1] == 1:
6161
right[i] = right[i + 1] + 1
62-
return max(left[i] + right[i] for i in range(n))
62+
return max(a + b for a, b in zip(left, right))
6363
```
6464

6565
### **Java**

solution/1400-1499/1493.Longest Subarray of 1's After Deleting One Element/Solution.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ def longestSubarray(self, nums: List[int]) -> int:
99
for i in range(n - 2, -1, -1):
1010
if nums[i + 1] == 1:
1111
right[i] = right[i + 1] + 1
12-
return max(left[i] + right[i] for i in range(n))
12+
return max(a + b for a, b in zip(left, right))

solution/1500-1599/1510.Stone Game IV/README.md

+188
Original file line numberDiff line numberDiff line change
@@ -67,22 +67,210 @@
6767

6868
<!-- 这里可写通用的实现逻辑 -->
6969

70+
**方法一:记忆化搜索**
71+
72+
我们设计一个函数 $dfs(i)$,表示当前石子堆中有 $i$ 个石子时,当前玩家是否能赢得比赛。如果当前玩家能赢得比赛,则返回 $true$,否则返回 $false$。那么答案即为 $dfs(n)$。
73+
74+
函数 $dfs(i)$ 的计算过程如下:
75+
76+
- 如果 $i \leq 0$,说明当前玩家无法进行任何操作,因此当前玩家输掉比赛,返回 $false$;
77+
- 否则,枚举当前玩家可以拿走的石子数量 $j$,其中 $j$ 为平方数,如果当前玩家拿走 $j$ 个石子后,另一个玩家无法赢得比赛,则当前玩家赢得比赛,返回 $true$。如果枚举完所有的 $j$,都无法满足上述条件,则当前玩家输掉比赛,返回 $false$。
78+
79+
为了避免重复计算,我们可以使用记忆化搜索,即使用数组 $f$ 记录函数 $dfs(i)$ 的计算结果。
80+
81+
时间复杂度 $O(n \times \sqrt{n})$,空间复杂度 $O(n)$。其中 $n$ 为石子堆中石子的数量。
82+
83+
**方法二:动态规划**
84+
85+
我们也可以使用动态规划求解本题。
86+
87+
定义数组 $f$,其中 $f[i]$ 表示当前石子堆中有 $i$ 个石子时,当前玩家是否能赢得比赛。如果当前玩家能赢得比赛,则 $f[i]$ 为 $true$,否则为 $false$。那么答案即为 $f[n]$。
88+
89+
我们在 $[1,..n]$ 的范围内枚举 $i$,并在 $[1,..i]$ 的范围内枚举 $j$,其中 $j$ 为平方数,如果当前玩家拿走 $j$ 个石子后,另一个玩家无法赢得比赛,则当前玩家赢得比赛,即 $f[i] = true$。如果枚举完所有的 $j$,都无法满足上述条件,则当前玩家输掉比赛,即 $f[i] = false$。因此我们可以得到状态转移方程:
90+
91+
$$
92+
f[i]=
93+
\begin{cases}
94+
true, & \text{if } \exists j \in [1,..i], j^2 \leq i \text{ and } f[i-j^2] = false\\
95+
false, & \text{otherwise}
96+
\end{cases}
97+
$$
98+
99+
最后,我们返回 $f[n]$ 即可。
100+
101+
时间复杂度 $O(n \times \sqrt{n})$,空间复杂度 $O(n)$。其中 $n$ 为石子堆中石子的数量。
102+
70103
<!-- tabs:start -->
71104

72105
### **Python3**
73106

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

76109
```python
110+
class Solution:
111+
def winnerSquareGame(self, n: int) -> bool:
112+
@cache
113+
def dfs(i):
114+
if i <= 0:
115+
return False
116+
j = 1
117+
while (k := (i - j * j)) >= 0:
118+
if not dfs(k):
119+
return True
120+
j += 1
121+
return False
122+
123+
return dfs(n)
124+
```
77125

126+
```python
127+
class Solution:
128+
def winnerSquareGame(self, n: int) -> bool:
129+
f = [False] * (n + 1)
130+
for i in range(1, n + 1):
131+
j = 1
132+
while j <= i // j:
133+
if not f[i - j * j]:
134+
f[i] = True
135+
break
136+
j += 1
137+
return f[n]
78138
```
79139

80140
### **Java**
81141

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

84144
```java
145+
class Solution {
146+
private Boolean[] f;
147+
148+
public boolean winnerSquareGame(int n) {
149+
f = new Boolean[n + 1];
150+
return dfs(n);
151+
}
152+
153+
private boolean dfs(int i) {
154+
if (i <= 0) {
155+
return false;
156+
}
157+
if (f[i] != null) {
158+
return f[i];
159+
}
160+
for (int j = 1; j <= i / j; ++j) {
161+
if (!dfs(i - j * j)) {
162+
return f[i] = true;
163+
}
164+
}
165+
return f[i] = false;
166+
}
167+
}
168+
```
169+
170+
```java
171+
class Solution {
172+
public boolean winnerSquareGame(int n) {
173+
boolean[] f = new boolean[n + 1];
174+
for (int i = 1; i <= n; ++i) {
175+
for (int j = 1; j <= i / j; ++j) {
176+
if (!f[i - j * j]) {
177+
f[i] = true;
178+
break;
179+
}
180+
}
181+
}
182+
return f[n];
183+
}
184+
}
185+
```
186+
187+
### **C++**
188+
189+
```cpp
190+
class Solution {
191+
public:
192+
bool winnerSquareGame(int n) {
193+
int f[n + 1];
194+
memset(f, 0, sizeof(f));
195+
function<bool(int)> dfs = [&](int i) -> bool {
196+
if (i <= 0) {
197+
return false;
198+
}
199+
if (f[i] != 0) {
200+
return f[i] == 1;
201+
}
202+
for (int j = 1; j <= i / j; ++j) {
203+
if (!dfs(i - j * j)) {
204+
f[i] = 1;
205+
return true;
206+
}
207+
}
208+
f[i] = -1;
209+
return false;
210+
};
211+
return dfs(n);
212+
}
213+
};
214+
```
215+
216+
```cpp
217+
class Solution {
218+
public:
219+
bool winnerSquareGame(int n) {
220+
bool f[n + 1];
221+
memset(f, false, sizeof(f));
222+
for (int i = 1; i <= n; ++i) {
223+
for (int j = 1; j <= i / j; ++j) {
224+
if (!f[i - j * j]) {
225+
f[i] = true;
226+
break;
227+
}
228+
}
229+
}
230+
return f[n];
231+
}
232+
};
233+
```
234+
235+
### **Go**
236+
237+
```go
238+
func winnerSquareGame(n int) bool {
239+
f := make([]int, n+1)
240+
var dfs func(int) bool
241+
dfs = func(i int) bool {
242+
if i <= 0 {
243+
return false
244+
}
245+
if f[i] != 0 {
246+
return f[i] == 1
247+
}
248+
for j := 1; j <= i/j; j++ {
249+
if !dfs(i - j*j) {
250+
f[i] = 1
251+
return true
252+
}
253+
}
254+
f[i] = -1
255+
return false
256+
}
257+
return dfs(n)
258+
}
259+
```
85260

261+
```go
262+
func winnerSquareGame(n int) bool {
263+
f := make([]bool, n+1)
264+
for i := 1; i <= n; i++ {
265+
for j := 1; j <= i/j; j++ {
266+
if !f[i-j*j] {
267+
f[i] = true
268+
break
269+
}
270+
}
271+
}
272+
return f[n]
273+
}
86274
```
87275

88276
### **...**

0 commit comments

Comments
 (0)