289. 生命游戏
给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态:1 即为活细胞(live),或 0 即为死细胞(dead)。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:
-
如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
-
如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
-
如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
-
如果死细胞周围正好有三个活细胞,则该位置死细胞复活;
根据当前状态,写一个函数来计算面板上所有细胞的下一个(一次更新后的)状态。下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是同时发生的。
示例:
输入:
[[0,1,0],[0,0,1],[1,1,1],[0,0,0]]
输出:
[ [0,0,0],[1,0,1],[0,1,1],[0,1,0]]
进阶:
你可以使用原地算法解决本题吗?请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
本题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?
1.m × n 格子面板
2.1 为活细胞,0 为死细胞
3.每个细胞遵循生存定律
4.计算更新一次后的结果(新状态)
示例:
输入:
[[0,1,0],[0,0,1],[1,1,1],[0,0,0]]
输出:
[ [0,0,0],[1,0,1],[0,1,1],[0,1,0]]
进阶:
你可以使用原地算法(见思路二)解决本题吗?请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
本题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?
解题思路:
思路(一):查找一个,遍地开花
因为题目是对原始序列进行修改,这样就可以声明另一个同样的序列,把原始序列内容全部赋值给新序列,然后对新序列比较计算适应生存规律,对原始序列修改。
-
计算面板长宽,声明一个新序列把board里的内容全部复制到新序列中
-
遍历新序列中的每一个元素,并计算八个位置的细胞是否alive计数
-
适应生存规律并修改原始序列位置上的值
-
遍历结束,修改后的原始数组即为新状态
C/C++题解:(点击蓝色阅读源码,或前往公众号回复“289”获取)
class Solution {
public:
void gameOfLife(vector<vector<int>>& board) {
Java题解:(点击蓝色阅读源码,或前往公众号回复“289”获取)
class Solution {
public void gameOfLife(int[][] board) {
Python题解:(点击蓝色阅读源码,或前往公众号回复“289”获取)
class Solution(object):
def gameOfLife(self, board):
""":type board: List[List[int]]"""
例题来自力扣网https://leetcode-cn.com/
思路(二):原地算法进阶
在原始序列上用另一组标记来记录细胞是否处于死活状态
-
遍历原始序列,计算周围元素活细胞个数
-
如果当前活细胞周围有少于2个或大于3个活细胞,把当前元素标为2
-
如果当前是死细胞,周围有3个活细胞,把当前元素标为-1
-
判断是活细胞还是死细胞根据是否大于0判断
-
最后从头到尾遍历一次,标为2的还原0,标为-1的还原1
python题解:(点击蓝色阅读源码,或前往公众号回复“289”获取)
class Solution(object):
def gameOfLife(self, board):
更多题解前往公众号免费获取