Skip to content

Commit

Permalink
feat: add solutions to lc problems: No.0292,0293 (#2308)
Browse files Browse the repository at this point in the history
  • Loading branch information
yanglbme authored Feb 4, 2024
1 parent 859c150 commit c33bcc7
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 89 deletions.
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;
}

0 comments on commit c33bcc7

Please sign in to comment.