289 生命游戏

本文最后更新于:2022年4月9日 中午


根据 百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。

给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态:1 即为活细胞(live),或 0 即为死细胞(dead)。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:

  1. 如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
  2. 如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
  3. 如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
  4. 如果死细胞周围正好有三个活细胞,则该位置死细胞复活;

根据当前状态,写一个函数来计算面板上所有细胞的下一个(一次更新后的)状态。下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是同时发生的。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
输入: 
[
[0,1,0],
[0,0,1],
[1,1,1],
[0,0,0]
]
输出:
[
[0,0,0],
[1,0,1],
[0,1,1],
[0,1,0]
]

进阶:

  • 你可以使用原地算法解决本题吗?请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
  • 本题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?

Solution

参考 @katsu@onlyyou 的思路

  • 拷贝矩阵,在副本上进行生存判断
  • 定义方向数组,避免多 if 条件判断
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# @lc code=start
class Solution:
def gameOfLife(self, board: List[List[int]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
res = copy.deepcopy(board)
row = len(board)
col = len(board[0])
# 定义八个方向:上,下,左,右,左上,左下,右上,右下
direction = [[-1,0],[1,0],[0,-1],[0,1],[-1,-1],[1,-1],[-1,1],[1,1]]
for i in range(row):
for j in range(col):
nums = 0
for k in range(8):
dx = direction[k][0] + i
dy = direction[k][1] + j
if dx>=0 and dx<row and dy>=0 and dy<col and res[dx][dy]==1:
nums += 1

if nums < 2:
board[i][j] = 0
elif nums > 3:
board[i][j] = 0
elif nums == 3:
board[i][j] = 1
# @lc code=end

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!