289. Game of Life

According to Wikipedia’s article: “The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970.”

The board is made up of an m x n grid of cells, where each cell has an initial state: live (represented by a 1) or dead (represented by a 0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article):

Any live cell with fewer than two live neighbors dies as if caused by under-population.
Any live cell with two or three live neighbors lives on to the next generation.
Any live cell with more than three live neighbors dies, as if by over-population.
Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.

The next state is created by applying the above rules simultaneously to every cell in the current state, where births and deaths occur simultaneously. Given the current state of the m x n grid board, return the next state.

在这里插入图片描述在这里插入图片描述https://leetcode.cn/problems/game-of-life/description/
思路:
生命游戏 ,简称为 生命 ,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。

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

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

下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是同时发生的。给你 m x n 网格面板 board 的当前状态,返回下一个状态。
题目分析

这道题主要就是模拟,遍历每一个格子,然后统计其周围八个格子的活细胞个数,来看这个格子的状态是否改变。
但难点在于:如果这个格子的状态改变,不能直接改变。这样会影响后面格子的统计。即题目中说的:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。

因此我们需要使用特殊值去标记发生改变的格子,从而根据特殊值可以知道这个格子原状态是什么,要更新的状态是什么。
我们使用:2表示活细胞变成死细胞,3表示死细胞变成活细胞。【这样的好处是最终是死细胞的都是偶数,活细胞的都是奇数,模2即结果;】

class Solution:
    def gameOfLife(self, board: List[List[int]]) -> None:
        m = len(board)      # 行数
        n = len(board[0])   # 列数
        for i in range(m):
            for j in range(n):
                count = 0   # 统计每个格子周围八个位置的活细胞数,每个格子计数重置为0
                for x in range(-1, 2):
                    for y in range(-1, 2):
                        # 枚举周围八个位置,其中去掉本身(x = y = 0)和越界的情况
                        if (x == 0 and y == 0) or i + x < 0 or i + x >= m or j + y < 0 or j + y >= n: continue
                        # 如果周围格子是活细胞(1)或者是活细胞变死细胞(2)的,都算一个活细胞
                        if board[i + x][j + y] == 1 or board[i + x][j + y] == 2: count += 1
                if board[i][j] == 1 and (count < 2 or count > 3): board[i][j] = 2   # 格子本身是活细胞,周围满足变成死细胞的条件,标记为2
                if board[i][j] == 0 and count == 3: board[i][j] = 3         # 格子本身是死细胞,周围满足复活条件,标记为3       
        for i in range(m):
            for j in range(n):
                # 死细胞为0,活细胞变成死细胞为2,都为偶数,模2为0,刚好是死细胞
                # 活细胞为1,死细胞变成活细胞为3,都为奇数,模2为1,刚好是活细胞
                board[i][j] %= 2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值