进阶:
你可以使用原地算法解决本题吗?请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
本题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?
原题出处:https://leetcode.cn/leetbook/read/top-interview-questions-hard/xwk53e/
解法一(python)
class Solution:
def gameOfLife(self, board: List[List[int]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
m, n = len(board), len(board[0])
directions = [(1, 0), (-1, 0), (0, 1), (0, -1), (1, 1), (-1, -1), (1, -1), (-1, 1)]
def count_live_neighbors(x, y):
count = 0
for dx, dy in directions:
nx, ny = x + dx, y + dy
if 0 <= nx < m and 0 <= ny < n and (board[nx][ny] == 1 or board[nx][ny] == -1):
count += 1
return count
for i in range(m):
for j in range(n):
live_neighbors = count_live_neighbors(i, j)
if board[i][j] == 1 and (live_neighbors < 2 or live_neighbors > 3):
board[i][j] = -1
elif board[i][j] == 0 and live_neighbors == 3:
board[i][j] = 2
for i in range(m):
for j in range(n):
if board[i][j] == 2:
board[i][j] = 1
elif board[i][j] == -1:
board[i][j] = 0
思路:
这题的核心思路是模拟细胞自动机的演化过程,根据给定的规则更新每个细胞的状态,然后形成下一个时刻的状态。以下是具体的思路:
-
遍历整个网格面板,对于每个细胞,统计其周围八个位置的活细胞数,这可以通过定义一个方向数组来实现。
-
根据规则更新每个细胞的状态:
- 如果一个活细胞周围的活细胞数少于两个,它会死亡(下一个状态为0或-1)。
- 如果一个活细胞周围有两个或三个活细胞,它会继续存活(下一个状态仍为1)。
- 如果一个活细胞周围有超过三个活细胞,它会死亡(下一个状态为0或-1)。
- 如果一个死细胞周围恰好有三个活细胞,它会复活(下一个状态为2)。
-
更新细胞状态:将所有标记为-1的活细胞设置为死细胞(状态为0),将所有标记为2的死细胞设置为活细胞(状态为1),从而得到下一个时刻的状态。
这个过程的关键在于,为了避免在更新过程中干扰其他细胞的计算,我们需要先标记状态的改变,然后在一次遍历结束后再统一更新状态。
这样,通过按照规则进行模拟,你就可以得到网格面板的下一个状态。这个思路能够有效地处理细胞状态的变化,并在每个时刻更新细胞状态,模拟出生命游戏的演化过程。