Skip to content
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

feat: add solutions to lc problems: No.0292,0293 #2308

Merged
merged 1 commit into from
Feb 4, 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
11 changes: 6 additions & 5 deletions solution/0200-0299/0292.Nim Game/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,20 @@

## 解法

### 方法一:数学推理
### 方法一:找规律

第一个得到 $4$ 的倍数(即 $n$ 能被 $4$ 整除)的将会输掉比赛。

证明:

1. 当 $n=4$,无论第一个玩家选择 $1/2/3$ 哪个数字,第二个玩家总能选择剩下的数字,**第一个玩家将会输掉比赛**。
1. 当 $4<n<8$,即 ($n=5,6,7$),第一个玩家可以相应地将数字减少为 $4$,那么 $4$ 这个死亡数字给到了第二个玩家,第二个玩家将会输掉比赛。
1. 当 $n=8$,无论第一个玩家选择 $1/2/3$ 哪个数字,都会把 $4<n<8$ 的数字留给第二个,**第一个玩家将会输掉比赛**。
1. 当 $n \lt 4$ 时,第一个玩家可以直接拿走所有的石头,所以第一个玩家将会赢得比赛。
1. 当 $n = 4$,无论第一个玩家选择 $1, 2, 3$ 哪个数字,第二个玩家总能选择剩下的数字,所以第一个玩家将会输掉比赛。
1. 当 $4 \lt n \lt 8$ 时,即 $n = 5, 6, 7$,第一个玩家可以相应地将数字减少为 $4$,那么 $4$ 这个死亡数字给到了第二个玩家,第二个玩家将会输掉比赛。
1. 当 $n = 8$,无论第一个玩家选择 $1, 2, 3$ 哪个数字,都会把 $4 \lt n \lt 8$ 的数字留给第二个,所以第一个玩家将会输掉比赛。
1. ...
1. 依次类推,当玩家拿到 $n$ 这个数字,且 $n$ 能被 $4$ 整除,他将会输掉比赛,否则他将赢得比赛。

时间复杂度 $O(1)$。
时间复杂度 $O(1)$,空间复杂度 $O(1)$

<!-- tabs:start -->

Expand Down
15 changes: 14 additions & 1 deletion solution/0200-0299/0292.Nim Game/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,20 @@ In all outcomes, your friend wins.

## Solutions

### Solution 1
### Solution 1: Finding the Pattern

The first player who gets a multiple of $4$ (i.e., $n$ can be divided by $4$) will lose the game.

Proof:

1. When $n \lt 4$, the first player can directly take all the stones, so the first player will win the game.
1. When $n = 4$, no matter whether the first player chooses $1, 2, 3$, the second player can always choose the remaining number, so the first player will lose the game.
1. When $4 \lt n \lt 8$, i.e., $n = 5, 6, 7$, the first player can correspondingly reduce the number to $4$, then the "death number" $4$ is given to the second player, and the second player will lose the game.
1. When $n = 8$, no matter whether the first player chooses $1, 2, 3$, it will leave a number between $4 \lt n \lt 8$ to the second player, so the first player will lose the game.
1. ...
1. By induction, when a player gets the number $n$, and $n$ can be divided by $4$, he will lose the game, otherwise, he will win the game.

The time complexity is $O(1)$, and the space complexity is $O(1)$.

<!-- tabs:start -->

Expand Down
74 changes: 46 additions & 28 deletions solution/0200-0299/0293.Flip Game/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,13 @@

## 解法

### 方法一
### 方法一:遍历 + 模拟

我们遍历字符串,如果当前字符和下一个字符都是 `+`,那么我们就将这两个字符变成 `-`,然后将结果加入到结果数组中,再将这两个字符变回 `+`。

遍历结束后,返回结果数组即可。

时间复杂度 $O(n^2)$,其中 $n$ 是字符串长度。忽略答案数组的空间复杂度,空间复杂度 $O(n)$ 或 $O(1)$。

<!-- tabs:start -->

Expand All @@ -48,8 +54,8 @@ class Solution:
def generatePossibleNextMoves(self, currentState: str) -> List[str]:
s = list(currentState)
ans = []
for i, c in enumerate(s[:-1]):
if c == "+" and s[i + 1] == "+":
for i, (a, b) in enumerate(pairwise(s)):
if a == b == "+":
s[i] = s[i + 1] = "-"
ans.append("".join(s))
s[i] = s[i + 1] = "+"
Expand All @@ -59,15 +65,15 @@ class Solution:
```java
class Solution {
public List<String> generatePossibleNextMoves(String currentState) {
char[] cs = currentState.toCharArray();
List<String> ans = new ArrayList<>();
for (int i = 0; i < cs.length - 1; ++i) {
if (cs[i] == '+' && cs[i + 1] == '+') {
cs[i] = '-';
cs[i + 1] = '-';
ans.add(String.valueOf(cs));
cs[i] = '+';
cs[i + 1] = '+';
char[] s = currentState.toCharArray();
for (int i = 0; i < s.length - 1; ++i) {
if (s[i] == '+' && s[i + 1] == '+') {
s[i] = '-';
s[i + 1] = '-';
ans.add(new String(s));
s[i] = '+';
s[i + 1] = '+';
}
}
return ans;
Expand All @@ -78,15 +84,13 @@ class Solution {
```cpp
class Solution {
public:
vector<string> generatePossibleNextMoves(string currentState) {
vector<string> generatePossibleNextMoves(string s) {
vector<string> ans;
for (int i = 0; i < currentState.size() - 1; ++i) {
if (currentState[i] == '+' && currentState[i + 1] == '+') {
currentState[i] = '-';
currentState[i + 1] = '-';
ans.push_back(currentState);
currentState[i] = '+';
currentState[i + 1] = '+';
for (int i = 0; i < s.size() - 1; ++i) {
if (s[i] == '+' && s[i + 1] == '+') {
s[i] = s[i + 1] = '-';
ans.emplace_back(s);
s[i] = s[i + 1] = '+';
}
}
return ans;
Expand All @@ -95,17 +99,31 @@ public:
```

```go
func generatePossibleNextMoves(currentState string) []string {
ans := []string{}
cs := []byte(currentState)
for i, c := range cs[1:] {
if c == '+' && cs[i] == '+' {
cs[i], cs[i+1] = '-', '-'
ans = append(ans, string(cs))
cs[i], cs[i+1] = '+', '+'
func generatePossibleNextMoves(currentState string) (ans []string) {
s := []byte(currentState)
for i := 0; i < len(s)-1; i++ {
if s[i] == '+' && s[i+1] == '+' {
s[i], s[i+1] = '-', '-'
ans = append(ans, string(s))
s[i], s[i+1] = '+', '+'
}
}
return ans
return
}
```

```ts
function generatePossibleNextMoves(currentState: string): string[] {
const s = currentState.split('');
const ans: string[] = [];
for (let i = 0; i < s.length - 1; ++i) {
if (s[i] === '+' && s[i + 1] === '+') {
s[i] = s[i + 1] = '-';
ans.push(s.join(''));
s[i] = s[i + 1] = '+';
}
}
return ans;
}
```

Expand Down
74 changes: 46 additions & 28 deletions solution/0200-0299/0293.Flip Game/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,13 @@

## Solutions

### Solution 1
### Solution 1: Traversal + Simulation

We traverse the string. If the current character and the next character are both `+`, we change these two characters to `-`, add the result to the result array, and then change these two characters back to `+`.

After the traversal ends, we return the result array.

The time complexity is $O(n^2)$, where $n$ is the length of the string. Ignoring the space complexity of the result array, the space complexity is $O(n)$ or $O(1)$.

<!-- tabs:start -->

Expand All @@ -44,8 +50,8 @@ class Solution:
def generatePossibleNextMoves(self, currentState: str) -> List[str]:
s = list(currentState)
ans = []
for i, c in enumerate(s[:-1]):
if c == "+" and s[i + 1] == "+":
for i, (a, b) in enumerate(pairwise(s)):
if a == b == "+":
s[i] = s[i + 1] = "-"
ans.append("".join(s))
s[i] = s[i + 1] = "+"
Expand All @@ -55,15 +61,15 @@ class Solution:
```java
class Solution {
public List<String> generatePossibleNextMoves(String currentState) {
char[] cs = currentState.toCharArray();
List<String> ans = new ArrayList<>();
for (int i = 0; i < cs.length - 1; ++i) {
if (cs[i] == '+' && cs[i + 1] == '+') {
cs[i] = '-';
cs[i + 1] = '-';
ans.add(String.valueOf(cs));
cs[i] = '+';
cs[i + 1] = '+';
char[] s = currentState.toCharArray();
for (int i = 0; i < s.length - 1; ++i) {
if (s[i] == '+' && s[i + 1] == '+') {
s[i] = '-';
s[i + 1] = '-';
ans.add(new String(s));
s[i] = '+';
s[i + 1] = '+';
}
}
return ans;
Expand All @@ -74,15 +80,13 @@ class Solution {
```cpp
class Solution {
public:
vector<string> generatePossibleNextMoves(string currentState) {
vector<string> generatePossibleNextMoves(string s) {
vector<string> ans;
for (int i = 0; i < currentState.size() - 1; ++i) {
if (currentState[i] == '+' && currentState[i + 1] == '+') {
currentState[i] = '-';
currentState[i + 1] = '-';
ans.push_back(currentState);
currentState[i] = '+';
currentState[i + 1] = '+';
for (int i = 0; i < s.size() - 1; ++i) {
if (s[i] == '+' && s[i + 1] == '+') {
s[i] = s[i + 1] = '-';
ans.emplace_back(s);
s[i] = s[i + 1] = '+';
}
}
return ans;
Expand All @@ -91,17 +95,31 @@ public:
```

```go
func generatePossibleNextMoves(currentState string) []string {
ans := []string{}
cs := []byte(currentState)
for i, c := range cs[1:] {
if c == '+' && cs[i] == '+' {
cs[i], cs[i+1] = '-', '-'
ans = append(ans, string(cs))
cs[i], cs[i+1] = '+', '+'
func generatePossibleNextMoves(currentState string) (ans []string) {
s := []byte(currentState)
for i := 0; i < len(s)-1; i++ {
if s[i] == '+' && s[i+1] == '+' {
s[i], s[i+1] = '-', '-'
ans = append(ans, string(s))
s[i], s[i+1] = '+', '+'
}
}
return ans
return
}
```

```ts
function generatePossibleNextMoves(currentState: string): string[] {
const s = currentState.split('');
const ans: string[] = [];
for (let i = 0; i < s.length - 1; ++i) {
if (s[i] === '+' && s[i + 1] === '+') {
s[i] = s[i + 1] = '-';
ans.push(s.join(''));
s[i] = s[i + 1] = '+';
}
}
return ans;
}
```

Expand Down
14 changes: 6 additions & 8 deletions solution/0200-0299/0293.Flip Game/Solution.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
class Solution {
public:
vector<string> generatePossibleNextMoves(string currentState) {
vector<string> generatePossibleNextMoves(string s) {
vector<string> ans;
for (int i = 0; i < currentState.size() - 1; ++i) {
if (currentState[i] == '+' && currentState[i + 1] == '+') {
currentState[i] = '-';
currentState[i + 1] = '-';
ans.push_back(currentState);
currentState[i] = '+';
currentState[i + 1] = '+';
for (int i = 0; i < s.size() - 1; ++i) {
if (s[i] == '+' && s[i + 1] == '+') {
s[i] = s[i + 1] = '-';
ans.emplace_back(s);
s[i] = s[i + 1] = '+';
}
}
return ans;
Expand Down
17 changes: 8 additions & 9 deletions solution/0200-0299/0293.Flip Game/Solution.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
func generatePossibleNextMoves(currentState string) []string {
ans := []string{}
cs := []byte(currentState)
for i, c := range cs[1:] {
if c == '+' && cs[i] == '+' {
cs[i], cs[i+1] = '-', '-'
ans = append(ans, string(cs))
cs[i], cs[i+1] = '+', '+'
func generatePossibleNextMoves(currentState string) (ans []string) {
s := []byte(currentState)
for i := 0; i < len(s)-1; i++ {
if s[i] == '+' && s[i+1] == '+' {
s[i], s[i+1] = '-', '-'
ans = append(ans, string(s))
s[i], s[i+1] = '+', '+'
}
}
return ans
return
}
16 changes: 8 additions & 8 deletions solution/0200-0299/0293.Flip Game/Solution.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
class Solution {
public List<String> generatePossibleNextMoves(String currentState) {
char[] cs = currentState.toCharArray();
List<String> ans = new ArrayList<>();
for (int i = 0; i < cs.length - 1; ++i) {
if (cs[i] == '+' && cs[i + 1] == '+') {
cs[i] = '-';
cs[i + 1] = '-';
ans.add(String.valueOf(cs));
cs[i] = '+';
cs[i + 1] = '+';
char[] s = currentState.toCharArray();
for (int i = 0; i < s.length - 1; ++i) {
if (s[i] == '+' && s[i + 1] == '+') {
s[i] = '-';
s[i + 1] = '-';
ans.add(new String(s));
s[i] = '+';
s[i + 1] = '+';
}
}
return ans;
Expand Down
4 changes: 2 additions & 2 deletions solution/0200-0299/0293.Flip Game/Solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ class Solution:
def generatePossibleNextMoves(self, currentState: str) -> List[str]:
s = list(currentState)
ans = []
for i, c in enumerate(s[:-1]):
if c == "+" and s[i + 1] == "+":
for i, (a, b) in enumerate(pairwise(s)):
if a == b == "+":
s[i] = s[i + 1] = "-"
ans.append("".join(s))
s[i] = s[i + 1] = "+"
Expand Down
12 changes: 12 additions & 0 deletions solution/0200-0299/0293.Flip Game/Solution.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
function generatePossibleNextMoves(currentState: string): string[] {
const s = currentState.split('');
const ans: string[] = [];
for (let i = 0; i < s.length - 1; ++i) {
if (s[i] === '+' && s[i + 1] === '+') {
s[i] = s[i + 1] = '-';
ans.push(s.join(''));
s[i] = s[i + 1] = '+';
}
}
return ans;
}