Skip to content

Commit b698cf8

Browse files
authored
feat: update lc problems (#3807)
1 parent da940a9 commit b698cf8

File tree

21 files changed

+1131
-17
lines changed

21 files changed

+1131
-17
lines changed

solution/0600-0699/0632.Smallest Range Covering Elements from K Lists/README.md

+6-9
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ tags:
3232
<pre>
3333
<strong>输入:</strong>nums = [[4,10,15,24,26], [0,9,12,20], [5,18,22,30]]
3434
<strong>输出:</strong>[20,24]
35-
<strong>解释:</strong>
35+
<strong>解释:</strong>
3636
列表 1:[4, 10, 15, 24, 26],24 在区间 [20,24] 中。
3737
列表 2:[0, 9, 12, 20],20 在区间 [20,24] 中。
3838
列表 3:[5, 18, 22, 30],22 在区间 [20,24] 中。
@@ -67,13 +67,11 @@ tags:
6767

6868
### 方法一:排序 + 滑动窗口
6969

70-
将每个数字 $v$ 及其所在的组 $i$,构成数据项 $(v, i)$,存放在一个新的列表或者数组中,记为 `t`
70+
我们将每个数字 $x$ 及其所在的组 $i$,构成数据项 $(x, i)$,存放在一个新的数组 $t$ 中,然后对 $t$ 按照数字的大小进行排序(类似于将多个有序数组合并成一个新的有序数组)
7171

72-
`t` 按照数字的大小进行排序(类似于将多个有序数组合并成一个新的有序数组)
72+
接下来,我们遍历 $t$ 中的每个数据项,只看其中数字所在的组,用哈希表记录滑动窗口内的数字出现的组,如果组数为 $k$,说明当前窗口满足题目要求,此时算出窗口的起始和结束位置,更新答案
7373

74-
然后遍历 `t` 中每个数据项,只看其中数字所在的组,用哈希表记录滑动窗口内的数字出现的组,如果组数为 $k$,说明当前窗口满足题目要求,此时算出窗口的起始和结束位置,更新答案。
75-
76-
时间复杂度 $O(n\log n)$。其中 $n$ 是所有数字的总数。
74+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为所有数组中数字的个数。
7775

7876
<!-- tabs:start -->
7977

@@ -125,7 +123,7 @@ class Solution {
125123
for (int[] e : t) {
126124
int b = e[0];
127125
int v = e[1];
128-
cnt.put(v, cnt.getOrDefault(v, 0) + 1);
126+
cnt.merge(v, 1, Integer::sum);
129127
while (cnt.size() == k) {
130128
int a = t[j][0];
131129
int w = t[j][1];
@@ -134,8 +132,7 @@ class Solution {
134132
ans[0] = a;
135133
ans[1] = b;
136134
}
137-
cnt.put(w, cnt.get(w) - 1);
138-
if (cnt.get(w) == 0) {
135+
if (cnt.merge(w, -1, Integer::sum) == 0) {
139136
cnt.remove(w);
140137
}
141138
++j;

solution/0600-0699/0632.Smallest Range Covering Elements from K Lists/README_EN.md

+9-4
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,13 @@ List 3: [5, 18, 22, 30], 22 is in range [20,24].
6161

6262
<!-- solution:start -->
6363

64-
### Solution 1
64+
### Solution 1: Sorting + Sliding Window
65+
66+
We construct a data item $(x, i)$ for each number $x$ and its group $i$, and store these items in a new array $t$. Then, we sort $t$ by the value of the numbers (similar to merging multiple sorted arrays into a new sorted array).
67+
68+
Next, we traverse each data item in $t$, focusing on the group to which each number belongs. We use a hash table to record the groups of numbers within the sliding window. If the number of groups is $k$, it means the current window meets the problem's requirements. At this point, we calculate the start and end positions of the window and update the answer.
69+
70+
The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the total number of numbers in all arrays.
6571

6672
<!-- tabs:start -->
6773

@@ -113,7 +119,7 @@ class Solution {
113119
for (int[] e : t) {
114120
int b = e[0];
115121
int v = e[1];
116-
cnt.put(v, cnt.getOrDefault(v, 0) + 1);
122+
cnt.merge(v, 1, Integer::sum);
117123
while (cnt.size() == k) {
118124
int a = t[j][0];
119125
int w = t[j][1];
@@ -122,8 +128,7 @@ class Solution {
122128
ans[0] = a;
123129
ans[1] = b;
124130
}
125-
cnt.put(w, cnt.get(w) - 1);
126-
if (cnt.get(w) == 0) {
131+
if (cnt.merge(w, -1, Integer::sum) == 0) {
127132
cnt.remove(w);
128133
}
129134
++j;

solution/0600-0699/0632.Smallest Range Covering Elements from K Lists/Solution.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public int[] smallestRange(List<List<Integer>> nums) {
1818
for (int[] e : t) {
1919
int b = e[0];
2020
int v = e[1];
21-
cnt.put(v, cnt.getOrDefault(v, 0) + 1);
21+
cnt.merge(v, 1, Integer::sum);
2222
while (cnt.size() == k) {
2323
int a = t[j][0];
2424
int w = t[j][1];
@@ -27,13 +27,12 @@ public int[] smallestRange(List<List<Integer>> nums) {
2727
ans[0] = a;
2828
ans[1] = b;
2929
}
30-
cnt.put(w, cnt.get(w) - 1);
31-
if (cnt.get(w) == 0) {
30+
if (cnt.merge(w, -1, Integer::sum) == 0) {
3231
cnt.remove(w);
3332
}
3433
++j;
3534
}
3635
}
3736
return ans;
3837
}
39-
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
---
2+
comments: true
3+
difficulty: 简单
4+
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3360.Stone%20Removal%20Game/README.md
5+
---
6+
7+
<!-- problem:start -->
8+
9+
# [3360. 移除石头游戏](https://leetcode.cn/problems/stone-removal-game)
10+
11+
[English Version](/solution/3300-3399/3360.Stone%20Removal%20Game/README_EN.md)
12+
13+
## 题目描述
14+
15+
<!-- description:start -->
16+
17+
<p>Alice 和 Bob 在玩一个游戏,他们俩轮流从一堆石头中移除石头,Alice 先进行操作。</p>
18+
19+
<ul>
20+
<li>Alice 在第一次操作中移除 <strong>恰好</strong>&nbsp;10 个石头。</li>
21+
<li>接下来的每次操作中,每位玩家移除的石头数 <strong>恰好</strong>&nbsp;为另一位玩家上一次操作的石头数减 1 。</li>
22+
</ul>
23+
24+
<p>第一位没法进行操作的玩家输掉这个游戏。</p>
25+
26+
<p>给你一个正整数&nbsp;<code>n</code>&nbsp;表示一开始石头的数目,如果 Alice 赢下这个游戏,请你返回&nbsp;<code>true</code>&nbsp;,否则返回 <code>false</code>&nbsp;。</p>
27+
28+
<p>&nbsp;</p>
29+
30+
<p><strong class="example">示例 1:</strong></p>
31+
32+
<div class="example-block">
33+
<p><span class="example-io"><b>输入:</b>n = 12</span></p>
34+
35+
<p><span class="example-io"><b>输出:</b>true</span></p>
36+
37+
<p><strong>解释:</strong></p>
38+
39+
<ul>
40+
<li>Alice 第一次操作中移除 10 个石头,剩下 2 个石头给 Bob 。</li>
41+
<li>Bob 无法移除 9 个石头,所以 Alice 赢下游戏。</li>
42+
</ul>
43+
</div>
44+
45+
<p><strong class="example">示例 2:</strong></p>
46+
47+
<div class="example-block">
48+
<p><span class="example-io"><b>输入:</b>n = 1</span></p>
49+
50+
<p><span class="example-io"><b>输出:</b>false</span></p>
51+
52+
<p><b>解释:</b></p>
53+
54+
<ul>
55+
<li>Alice 无法移除 10 个石头,所以 Alice 输掉游戏。</li>
56+
</ul>
57+
</div>
58+
59+
<p>&nbsp;</p>
60+
61+
<p><strong>提示:</strong></p>
62+
63+
<ul>
64+
<li><code>1 &lt;= n &lt;= 50</code></li>
65+
</ul>
66+
67+
<!-- description:end -->
68+
69+
## 解法
70+
71+
<!-- solution:start -->
72+
73+
### 方法一:模拟
74+
75+
我们根据题意模拟游戏的过程,直到无法继续游戏为止。
76+
77+
具体地,我们维护两个变量 $x$ 和 $k$,分别表示当前可以移除的石头数和已经进行的操作次数。初始时 $x = 10$, $k = 0$。
78+
79+
在每一轮操作中,如果当前可以移除的石头数 $x$ 不超过剩余的石头数 $n$,那么我们移除 $x$ 个石头,并将 $x$ 减小 $1$,然后将 $k$ 增加 $1$。否则,我们无法进行操作,游戏结束。
80+
81+
最后,我们判断 $k$ 的奇偶性,如果 $k$ 是奇数,那么 Alice 赢得了游戏,否则 Bob 赢得了游戏。
82+
83+
时间复杂度 $O(\sqrt{n})$。其中 $n$ 是石头的数目。空间复杂度 $O(1)$。
84+
85+
<!-- tabs:start -->
86+
87+
#### Python3
88+
89+
```python
90+
class Solution:
91+
def canAliceWin(self, n: int) -> bool:
92+
x, k = 10, 0
93+
while n >= x:
94+
n -= x
95+
x -= 1
96+
k += 1
97+
return k % 2 == 1
98+
```
99+
100+
#### Java
101+
102+
```java
103+
class Solution {
104+
public boolean canAliceWin(int n) {
105+
int x = 10, k = 0;
106+
while (n >= x) {
107+
n -= x;
108+
--x;
109+
++k;
110+
}
111+
return k % 2 == 1;
112+
}
113+
}
114+
```
115+
116+
#### C++
117+
118+
```cpp
119+
class Solution {
120+
public:
121+
bool canAliceWin(int n) {
122+
int x = 10, k = 0;
123+
while (n >= x) {
124+
n -= x;
125+
--x;
126+
++k;
127+
}
128+
return k % 2;
129+
}
130+
};
131+
```
132+
133+
#### Go
134+
135+
```go
136+
func canAliceWin(n int) bool {
137+
x, k := 10, 0
138+
for n >= x {
139+
n -= x
140+
x--
141+
k++
142+
}
143+
return k%2 == 1
144+
}
145+
```
146+
147+
#### TypeScript
148+
149+
```ts
150+
function canAliceWin(n: number): boolean {
151+
let [x, k] = [10, 0];
152+
while (n >= x) {
153+
n -= x;
154+
--x;
155+
++k;
156+
}
157+
return k % 2 === 1;
158+
}
159+
```
160+
161+
<!-- tabs:end -->
162+
163+
<!-- solution:end -->
164+
165+
<!-- problem:end -->

0 commit comments

Comments
 (0)