Skip to content

Commit 282c38b

Browse files
committed
feat: add solutions to lc problem: No.0289
No.0289.Game of Life
1 parent 9f4cd92 commit 282c38b

File tree

8 files changed

+434
-361
lines changed

8 files changed

+434
-361
lines changed

solution/0200-0299/0289.Game of Life/README.md

+148-158
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,15 @@
5959

6060
<!-- 这里可写通用的实现逻辑 -->
6161

62-
由于细胞的存活状态变化是同时进行的,因此不能直接遍历格子,依次修改每个细胞的状态,否则前面细胞的状态变化将会影响到下一个要遍历到的细胞的状态。
62+
**方法一:原地标记**
6363

64-
因此,可以复制 board 样本,每次判断复制样本 cb 中的每个格子,然后对应修改 board 每个细胞的状态。空间复杂度复杂度 `O(mn)`
64+
我们不妨定义两个新的状态,其中状态 $2$ 表示活细胞在下一个状态转为死细胞,状态 $-1$ 表示死细胞在下一个状态转为活细胞。那么,对于当前遍历到的格子,如果格子大于 $0$,就表示当前格子是活细胞,否则就是死细胞
6565

66-
也可以多定义两个状态,`status = 2` 表示从活细胞转死细胞,`status = 3` 表示从死细胞转活细胞。最后将 `status = 2` 的细胞状态置为 0,而将 `status = 3` 的细胞状态置为 1。空间复杂度 `O(1)`
66+
因此,我们可以遍历整个面板,对于每个格子,统计其周围的活细胞数目,用变量 $live$ 表示。如果当前格子是活细胞,那么当 $live \lt 2$ 或者 $live \gt 3$ 时,当前格子的下一个状态是死细胞,即状态 $2$;如果当前格子是死细胞,那么当 $live = 3$ 时,当前格子的下一个状态是活细胞,即状态 $-1$。
67+
68+
最后,我们再遍历一遍面板,将状态 $2$ 的格子更新为死细胞,将状态 $-1$ 的格子更新为活细胞。
69+
70+
时间复杂度 $O(m \times n)$,其中 $m$ 和 $n$ 分别是面板的行数和列数。我们需要遍历整个面板。空间复杂度 $O(1)$。
6771

6872
<!-- tabs:start -->
6973

@@ -74,47 +78,24 @@
7478
```python
7579
class Solution:
7680
def gameOfLife(self, board: List[List[int]]) -> None:
77-
"""
78-
Do not return anything, modify board in-place instead.
79-
"""
80-
m, n = len(board), len(board[0])
81-
cb = [[board[i][j] for j in range(n)] for i in range(m)]
82-
dirs = [[-1, 0], [1, 0], [0, -1], [0, 1], [-1, -1], [-1, 1], [1, -1], [1, 1]]
83-
for i in range(m):
84-
for j in range(n):
85-
cnt = sum(
86-
cb[i + a][j + b]
87-
for a, b in dirs
88-
if 0 <= i + a < m and 0 <= j + b < n
89-
)
90-
if cb[i][j] == 1 and (cnt < 2 or cnt > 3):
91-
board[i][j] = 0
92-
elif cb[i][j] == 0 and (cnt == 3):
93-
board[i][j] = 1
94-
```
95-
96-
```python
97-
class Solution:
98-
def gameOfLife(self, board: List[List[int]]) -> None:
99-
"""
100-
Do not return anything, modify board in-place instead.
101-
"""
10281
m, n = len(board), len(board[0])
103-
dirs = [[-1, 0], [1, 0], [0, -1], [0, 1],
104-
[-1, -1], [-1, 1], [1, -1], [1, 1]]
10582
for i in range(m):
10683
for j in range(n):
107-
cnt = sum(1 for a, b in dirs if 0 <= i + a < m and 0 <=
108-
j + b < n and board[i + a][j + b] in (1, 2))
109-
if board[i][j] == 1 and (cnt < 2 or cnt > 3):
110-
# 活细胞转死细胞
84+
live = -board[i][j]
85+
for x in range(i - 1, i + 2):
86+
for y in range(j - 1, j + 2):
87+
if 0 <= x < m and 0 <= y < n and board[x][y] > 0:
88+
live += 1
89+
if board[i][j] and (live < 2 or live > 3):
11190
board[i][j] = 2
112-
elif board[i][j] == 0 and (cnt == 3):
113-
# 死细胞转活细胞
114-
board[i][j] = 3
91+
if board[i][j] == 0 and live == 3:
92+
board[i][j] = -1
11593
for i in range(m):
11694
for j in range(n):
117-
board[i][j] %= 2
95+
if board[i][j] == 2:
96+
board[i][j] = 0
97+
elif board[i][j] == -1:
98+
board[i][j] = 1
11899
```
119100

120101
### **Java**
@@ -125,59 +106,31 @@ class Solution:
125106
class Solution {
126107
public void gameOfLife(int[][] board) {
127108
int m = board.length, n = board[0].length;
128-
int[][] cb = new int[m][n];
129-
for (int i = 0; i < m; ++i) {
130-
for (int j = 0; j < n; ++j) {
131-
cb[i][j] = board[i][j];
132-
}
133-
}
134-
int[][] dirs = new int[][]{{0, -1}, {0, 1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
135-
for (int i = 0; i < m; ++i) {
136-
for (int j = 0; j < n; ++j) {
137-
int cnt = 0;
138-
for (int[] dir : dirs) {
139-
int x = i + dir[0], y = j + dir[1];
140-
if (x >= 0 && x < m && y >= 0 && y < n) {
141-
cnt += cb[x][y];
142-
}
143-
}
144-
if (cb[i][j] == 1 && (cnt < 2 || cnt > 3)) {
145-
board[i][j] = 0;
146-
} else if (cb[i][j] == 0 && cnt == 3) {
147-
board[i][j] = 1;
148-
}
149-
}
150-
}
151-
}
152-
}
153-
```
154-
155-
```java
156-
class Solution {
157-
public void gameOfLife(int[][] board) {
158-
int m = board.length, n = board[0].length;
159-
int[][] dirs
160-
= new int[][] {{0, -1}, {0, 1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
161109
for (int i = 0; i < m; ++i) {
162110
for (int j = 0; j < n; ++j) {
163-
int cnt = 0;
164-
for (int[] dir : dirs) {
165-
int x = i + dir[0], y = j + dir[1];
166-
if (x >= 0 && x < m && y >= 0 && y < n
167-
&& (board[x][y] == 1 || board[x][y] == 2)) {
168-
++cnt;
111+
int live = -board[i][j];
112+
for (int x = i - 1; x <= i + 1; ++x) {
113+
for (int y = j - 1; y <= j + 1; ++y) {
114+
if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] > 0) {
115+
++live;
116+
}
169117
}
170118
}
171-
if (board[i][j] == 1 && (cnt < 2 || cnt > 3)) {
119+
if (board[i][j] == 1 && (live < 2 || live > 3)) {
172120
board[i][j] = 2;
173-
} else if (board[i][j] == 0 && cnt == 3) {
174-
board[i][j] = 3;
121+
}
122+
if (board[i][j] == 0 && live == 3) {
123+
board[i][j] = -1;
175124
}
176125
}
177126
}
178127
for (int i = 0; i < m; ++i) {
179128
for (int j = 0; j < n; ++j) {
180-
board[i][j] %= 2;
129+
if (board[i][j] == 2) {
130+
board[i][j] = 0;
131+
} else if (board[i][j] == -1) {
132+
board[i][j] = 1;
133+
}
181134
}
182135
}
183136
}
@@ -191,115 +144,152 @@ class Solution {
191144
public:
192145
void gameOfLife(vector<vector<int>>& board) {
193146
int m = board.size(), n = board[0].size();
194-
vector<vector<int>> cb(m, vector<int>(n, 0));
195-
for (int i = 0; i < m; ++i)
196-
for (int j = 0; j < n; ++j)
197-
cb[i][j] = board[i][j];
198-
199-
vector<vector<int>> dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
200147
for (int i = 0; i < m; ++i) {
201148
for (int j = 0; j < n; ++j) {
202-
int cnt = 0;
203-
for (auto& dir : dirs) {
204-
int x = i + dir[0], y = j + dir[1];
205-
if (x >= 0 && x < m && y >= 0 && y < n) cnt += cb[x][y];
149+
int live = -board[i][j];
150+
for (int x = i - 1; x <= i + 1; ++x) {
151+
for (int y = j - 1; y <= j + 1; ++y) {
152+
if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] > 0) {
153+
++live;
154+
}
155+
}
156+
}
157+
if (board[i][j] == 1 && (live < 2 || live > 3)) {
158+
board[i][j] = 2;
159+
}
160+
if (board[i][j] == 0 && live == 3) {
161+
board[i][j] = -1;
206162
}
207-
if (cb[i][j] == 1 && (cnt < 2 || cnt > 3))
208-
board[i][j] = 0;
209-
else if (cb[i][j] == 0 && cnt == 3)
210-
board[i][j] = 1;
211163
}
212164
}
213-
}
214-
};
215-
```
216-
217-
```cpp
218-
class Solution {
219-
public:
220-
void gameOfLife(vector<vector<int>>& board) {
221-
int m = board.size(), n = board[0].size();
222-
vector<vector<int>> dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
223165
for (int i = 0; i < m; ++i) {
224166
for (int j = 0; j < n; ++j) {
225-
int cnt = 0;
226-
for (auto& dir : dirs) {
227-
int x = i + dir[0], y = j + dir[1];
228-
if (x >= 0 && x < m && y >= 0 && y < n && (board[x][y] == 1 || board[x][y] == 2)) ++cnt;
167+
if (board[i][j] == 2) {
168+
board[i][j] = 0;
169+
} else if (board[i][j] == -1) {
170+
board[i][j] = 1;
229171
}
230-
if (board[i][j] == 1 && (cnt < 2 || cnt > 3))
231-
board[i][j] = 2;
232-
else if (board[i][j] == 0 && cnt == 3)
233-
board[i][j] = 3;
234172
}
235173
}
236-
for (int i = 0; i < m; ++i)
237-
for (int j = 0; j < n; ++j)
238-
board[i][j] %= 2;
239174
}
240175
};
241176
```
242177
243178
### **Go**
244179
245-
```go
246-
func gameOfLife(board [][]int) {
247-
m, n := len(board), len(board[0])
248-
cb := make([][]int, m)
249-
for i := range cb {
250-
cb[i] = make([]int, n)
251-
for j := 0; j < n; j++ {
252-
cb[i][j] = board[i][j]
253-
}
254-
}
255-
dirs := [8][2]int{{0, -1}, {0, 1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}}
256-
for i := 0; i < m; i++ {
257-
for j := 0; j < n; j++ {
258-
cnt := 0
259-
for _, dir := range dirs {
260-
x, y := i + dir[0], j + dir[1]
261-
if x >= 0 && x < m && y >= 0 && y < n {
262-
cnt += cb[x][y]
263-
}
264-
}
265-
if cb[i][j] == 1 && (cnt < 2 || cnt > 3) {
266-
board[i][j] = 0
267-
} else if cb[i][j] == 0 && cnt == 3 {
268-
board[i][j] = 1
269-
}
270-
}
271-
}
272-
}
273-
```
274-
275180
```go
276181
func gameOfLife(board [][]int) {
277182
m, n := len(board), len(board[0])
278-
dirs := [8][2]int{{0, -1}, {0, 1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}}
279183
for i := 0; i < m; i++ {
280-
for j := 0; j < n; j++ {
281-
cnt := 0
282-
for _, dir := range dirs {
283-
x, y := i+dir[0], j+dir[1]
284-
if x >= 0 && x < m && y >= 0 && y < n && (board[x][y] == 1 || board[x][y] == 2) {
285-
cnt++
184+
for j, v := range board[i] {
185+
live := -v
186+
for x := i - 1; x <= i+1; x++ {
187+
for y := j - 1; y <= j+1; y++ {
188+
if x >= 0 && x < m && y >= 0 && y < n && board[x][y] > 0 {
189+
live++
190+
}
286191
}
287192
}
288-
if board[i][j] == 1 && (cnt < 2 || cnt > 3) {
193+
if v == 1 && (live < 2 || live > 3) {
289194
board[i][j] = 2
290-
} else if board[i][j] == 0 && cnt == 3 {
291-
board[i][j] = 3
195+
}
196+
if v == 0 && live == 3 {
197+
board[i][j] = -1
292198
}
293199
}
294200
}
295201
for i := 0; i < m; i++ {
296-
for j := 0; j < n; j++ {
297-
board[i][j] %= 2
202+
for j, v := range board[i] {
203+
if v == 2 {
204+
board[i][j] = 0
205+
}
206+
if v == -1 {
207+
board[i][j] = 1
208+
}
298209
}
299210
}
300211
}
301212
```
302213

214+
### **TypeScript**
215+
216+
```ts
217+
/**
218+
Do not return anything, modify board in-place instead.
219+
*/
220+
function gameOfLife(board: number[][]): void {
221+
const m = board.length;
222+
const n = board[0].length;
223+
for (let i = 0; i < m; ++i) {
224+
for (let j = 0; j < n; ++j) {
225+
let live = -board[i][j];
226+
for (let x = i - 1; x <= i + 1; ++x) {
227+
for (let y = j - 1; y <= j + 1; ++y) {
228+
if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] > 0) {
229+
++live;
230+
}
231+
}
232+
}
233+
if (board[i][j] === 1 && (live < 2 || live > 3)) {
234+
board[i][j] = 2;
235+
}
236+
if (board[i][j] === 0 && live === 3) {
237+
board[i][j] = -1;
238+
}
239+
}
240+
}
241+
for (let i = 0; i < m; ++i) {
242+
for (let j = 0; j < n; ++j) {
243+
if (board[i][j] === 2) {
244+
board[i][j] = 0;
245+
}
246+
if (board[i][j] === -1) {
247+
board[i][j] = 1;
248+
}
249+
}
250+
}
251+
}
252+
```
253+
254+
### **C#**
255+
256+
```cs
257+
public class Solution {
258+
public void GameOfLife(int[][] board) {
259+
int m = board.Length;
260+
int n = board[0].Length;
261+
for (int i = 0; i < m; ++i) {
262+
for (int j = 0; j < n; ++j) {
263+
int live = -board[i][j];
264+
for (int x = i - 1; x <= i + 1; ++x) {
265+
for (int y = j - 1; y <= j + 1; ++y) {
266+
if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] > 0) {
267+
++live;
268+
}
269+
}
270+
}
271+
if (board[i][j] == 1 && (live < 2 || live > 3)) {
272+
board[i][j] = 2;
273+
}
274+
if (board[i][j] == 0 && live == 3) {
275+
board[i][j] = -1;
276+
}
277+
}
278+
}
279+
for (int i = 0; i < m; ++i) {
280+
for (int j = 0; j < n; ++j) {
281+
if (board[i][j] == 2) {
282+
board[i][j] = 0;
283+
}
284+
if (board[i][j] == -1) {
285+
board[i][j] = 1;
286+
}
287+
}
288+
}
289+
}
290+
}
291+
```
292+
303293
### **...**
304294

305295
```

0 commit comments

Comments
 (0)