Skip to content

feat: update lc problems #3807

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ tags:
<pre>
<strong>输入:</strong>nums = [[4,10,15,24,26], [0,9,12,20], [5,18,22,30]]
<strong>输出:</strong>[20,24]
<strong>解释:</strong>
<strong>解释:</strong>
列表 1:[4, 10, 15, 24, 26],24 在区间 [20,24] 中。
列表 2:[0, 9, 12, 20],20 在区间 [20,24] 中。
列表 3:[5, 18, 22, 30],22 在区间 [20,24] 中。
Expand Down Expand Up @@ -67,13 +67,11 @@ tags:

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

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

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

然后遍历 `t` 中每个数据项,只看其中数字所在的组,用哈希表记录滑动窗口内的数字出现的组,如果组数为 $k$,说明当前窗口满足题目要求,此时算出窗口的起始和结束位置,更新答案。

时间复杂度 $O(n\log n)$。其中 $n$ 是所有数字的总数。
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为所有数组中数字的个数。

<!-- tabs:start -->

Expand Down Expand Up @@ -125,7 +123,7 @@ class Solution {
for (int[] e : t) {
int b = e[0];
int v = e[1];
cnt.put(v, cnt.getOrDefault(v, 0) + 1);
cnt.merge(v, 1, Integer::sum);
while (cnt.size() == k) {
int a = t[j][0];
int w = t[j][1];
Expand All @@ -134,8 +132,7 @@ class Solution {
ans[0] = a;
ans[1] = b;
}
cnt.put(w, cnt.get(w) - 1);
if (cnt.get(w) == 0) {
if (cnt.merge(w, -1, Integer::sum) == 0) {
cnt.remove(w);
}
++j;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,13 @@ List 3: [5, 18, 22, 30], 22 is in range [20,24].

<!-- solution:start -->

### Solution 1
### Solution 1: Sorting + Sliding Window

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).

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.

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.

<!-- tabs:start -->

Expand Down Expand Up @@ -113,7 +119,7 @@ class Solution {
for (int[] e : t) {
int b = e[0];
int v = e[1];
cnt.put(v, cnt.getOrDefault(v, 0) + 1);
cnt.merge(v, 1, Integer::sum);
while (cnt.size() == k) {
int a = t[j][0];
int w = t[j][1];
Expand All @@ -122,8 +128,7 @@ class Solution {
ans[0] = a;
ans[1] = b;
}
cnt.put(w, cnt.get(w) - 1);
if (cnt.get(w) == 0) {
if (cnt.merge(w, -1, Integer::sum) == 0) {
cnt.remove(w);
}
++j;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public int[] smallestRange(List<List<Integer>> nums) {
for (int[] e : t) {
int b = e[0];
int v = e[1];
cnt.put(v, cnt.getOrDefault(v, 0) + 1);
cnt.merge(v, 1, Integer::sum);
while (cnt.size() == k) {
int a = t[j][0];
int w = t[j][1];
Expand All @@ -27,13 +27,12 @@ public int[] smallestRange(List<List<Integer>> nums) {
ans[0] = a;
ans[1] = b;
}
cnt.put(w, cnt.get(w) - 1);
if (cnt.get(w) == 0) {
if (cnt.merge(w, -1, Integer::sum) == 0) {
cnt.remove(w);
}
++j;
}
}
return ans;
}
}
}
165 changes: 165 additions & 0 deletions solution/3300-3399/3360.Stone Removal Game/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
---
comments: true
difficulty: 简单
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3360.Stone%20Removal%20Game/README.md
---

<!-- problem:start -->

# [3360. 移除石头游戏](https://leetcode.cn/problems/stone-removal-game)

[English Version](/solution/3300-3399/3360.Stone%20Removal%20Game/README_EN.md)

## 题目描述

<!-- description:start -->

<p>Alice 和 Bob 在玩一个游戏,他们俩轮流从一堆石头中移除石头,Alice 先进行操作。</p>

<ul>
<li>Alice 在第一次操作中移除 <strong>恰好</strong>&nbsp;10 个石头。</li>
<li>接下来的每次操作中,每位玩家移除的石头数 <strong>恰好</strong>&nbsp;为另一位玩家上一次操作的石头数减 1 。</li>
</ul>

<p>第一位没法进行操作的玩家输掉这个游戏。</p>

<p>给你一个正整数&nbsp;<code>n</code>&nbsp;表示一开始石头的数目,如果 Alice 赢下这个游戏,请你返回&nbsp;<code>true</code>&nbsp;,否则返回 <code>false</code>&nbsp;。</p>

<p>&nbsp;</p>

<p><strong class="example">示例 1:</strong></p>

<div class="example-block">
<p><span class="example-io"><b>输入:</b>n = 12</span></p>

<p><span class="example-io"><b>输出:</b>true</span></p>

<p><strong>解释:</strong></p>

<ul>
<li>Alice 第一次操作中移除 10 个石头,剩下 2 个石头给 Bob 。</li>
<li>Bob 无法移除 9 个石头,所以 Alice 赢下游戏。</li>
</ul>
</div>

<p><strong class="example">示例 2:</strong></p>

<div class="example-block">
<p><span class="example-io"><b>输入:</b>n = 1</span></p>

<p><span class="example-io"><b>输出:</b>false</span></p>

<p><b>解释:</b></p>

<ul>
<li>Alice 无法移除 10 个石头,所以 Alice 输掉游戏。</li>
</ul>
</div>

<p>&nbsp;</p>

<p><strong>提示:</strong></p>

<ul>
<li><code>1 &lt;= n &lt;= 50</code></li>
</ul>

<!-- description:end -->

## 解法

<!-- solution:start -->

### 方法一:模拟

我们根据题意模拟游戏的过程,直到无法继续游戏为止。

具体地,我们维护两个变量 $x$ 和 $k$,分别表示当前可以移除的石头数和已经进行的操作次数。初始时 $x = 10$, $k = 0$。

在每一轮操作中,如果当前可以移除的石头数 $x$ 不超过剩余的石头数 $n$,那么我们移除 $x$ 个石头,并将 $x$ 减小 $1$,然后将 $k$ 增加 $1$。否则,我们无法进行操作,游戏结束。

最后,我们判断 $k$ 的奇偶性,如果 $k$ 是奇数,那么 Alice 赢得了游戏,否则 Bob 赢得了游戏。

时间复杂度 $O(\sqrt{n})$。其中 $n$ 是石头的数目。空间复杂度 $O(1)$。

<!-- tabs:start -->

#### Python3

```python
class Solution:
def canAliceWin(self, n: int) -> bool:
x, k = 10, 0
while n >= x:
n -= x
x -= 1
k += 1
return k % 2 == 1
```

#### Java

```java
class Solution {
public boolean canAliceWin(int n) {
int x = 10, k = 0;
while (n >= x) {
n -= x;
--x;
++k;
}
return k % 2 == 1;
}
}
```

#### C++

```cpp
class Solution {
public:
bool canAliceWin(int n) {
int x = 10, k = 0;
while (n >= x) {
n -= x;
--x;
++k;
}
return k % 2;
}
};
```

#### Go

```go
func canAliceWin(n int) bool {
x, k := 10, 0
for n >= x {
n -= x
x--
k++
}
return k%2 == 1
}
```

#### TypeScript

```ts
function canAliceWin(n: number): boolean {
let [x, k] = [10, 0];
while (n >= x) {
n -= x;
--x;
++k;
}
return k % 2 === 1;
}
```

<!-- tabs:end -->

<!-- solution:end -->

<!-- problem:end -->
Loading
Loading