leetcode289.生命游戏

生命游戏

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

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

如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;

如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;

如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;

如果死细胞周围正好有三个活细胞,则该位置死细胞复活;

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

示例 1:

输入:board = [[0,1,0],[0,0,1],[1,1,1],[0,0,0]]

17425c6771ac4c4ab73da389c8e92ec6.png

输出:[[0,0,0],[1,0,1],[0,1,1],[0,1,0]]

示例 2:

输入:board = [[1,1],[1,0]]

d2ae71171ebc41f3a6c0ca3100455bfd.jpg

输出:[[1,1],[1,1]]

最优解决方案

生命游戏的核心就是根据每个细胞周围的活细胞的数量来决定它下一个状态是存活还是死亡。但是我们不能直接改变细胞的状态,因为这样会影响到其他细胞的判断。所以我们需要用一种方法来暂时记录下一个状态,然后再统一更新。

我的思路就是用-1和2来表示状态的变化,-1表示从存活变成死亡,2表示从死亡变成存活。这样在扫描周围活细胞的数量时,我们可以把-1当做存活,2当做死亡,就不会出错了。最后我们再把-1和2还原成0和1,就得到了最终结果。

代码

func gameOfLife(board [][]int) {

    // 定义八个方向

    dirs := [][]int{{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}}

    // 遍历每个细胞

    for i := range board {

        for j := range board[i] {

            // 统计周围活细胞的数量

            liveCount := 0

            for _, dir := range dirs {

                x := i + dir[0]

                y := j + dir[1]

                // 判断边界条件和是否为活细胞

                if x >= 0 && x < len(board) && y >= 0 && y < len(board[i]) && (board[x][y] == 1 || board[x][y] == - 1) {

                    liveCount++

                }

            }

            // 根据规则更新下一个状态

            if board[i][j] == 0 { // 死细胞

                if liveCount == 3 { // 死->活

                    board[i][j] = 2 

                }

            } else { // 活细胞

                if liveCount <2 || liveCount >3 { // 活->死

                    board[i][j] = - 1 

                }

            }

        }

    }

    // 将- 1和2还原为0和1

    for i := range board {

        for j := range board[i] {

            if board[i][j] > 0 {

                board[i][j] = 1

            } else {

                board[i][j] = 0 

            }

        }

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值