LeetCode-289 Game of Life

题目描述

According to the 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."

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

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

Write a function to compute the next state (after one update) of the board given its current state. The next state is created by applying the above rules simultaneously to every cell in the current state, where births and deaths occur simultaneously.

题目大意

给定一个二维数组,数组中只包含0和1(其中0代表死亡,1代表存活),要求根据以下的状态计算方法,计算出该矩阵的下一个状态:

1. 若当前位置为1,且其邻居中1的个数少于2个,则将其置0;(其中的邻居为该位置的相邻的八个方向的位置)

2. 若当前位置为1,且其邻居中的1的个数为2个或3个,则保持1不变;

3. 若当前位置为1,且其邻居中的1的个数大于3,则将其置0;

4. 若当前位置为0,且其邻居中的1的个数等于3,则将其置1,否则不变。

(PS:要求在当前的数组中进行操作,尽量不要用多余的数组空间)

示例

E1

Input: 
[
  [0,1,0],
  [0,0,1],
  [1,1,1],
  [0,0,0]
]
Output: 
[
  [0,0,0],
  [1,0,1],
  [0,1,1],
  [0,1,0]
]

解题思路

简单遍历一边数组,同时判断其邻居的状态,根据要求进行改变,为了不影响之后的位置对其邻居的判断,可以将其其改变为2和3(2:从0变成1,3:从1变成0),因此若邻居中出现2则代表其等于0,若出现3则代表为1 。

第二遍遍历一遍数组,将2和3分别改为1和0 。即完成在当前数组进行状态的变化。

复杂度分析

时间复杂度:O(N)

空间复杂度:O(1)

代码

class Solution {
public:
    void gameOfLife(vector<vector<int>>& board) {
        int m, n;
        m = board.size();
        if(m)
            n = board[0].size();
        else
            return;
        // 第一遍遍历数组
        for(int i = 0; i < m; ++i) {
            for(int j = 0; j < n; ++j) {
                int live = 0;
                // 查找邻居中的1的数量
                for(int k = 0; k < 8; ++k) {
                    int tx = i + nei[k][0], ty = j + nei[k][1];
                    if(tx >= 0 && tx < m && ty >= 0 && ty < n) {
                        // 注意若其中存在3,则也代表为1
                        live += board[tx][ty] % 2;
                    }
                }
                // 根据规则进行变化,若其为0->1的变化则置2,若为1->0的变化则置3
                if(board[i][j]) {
                    if(live < 2 || live > 3)
                        board[i][j] = 3;
                }
                else {
                    if(live == 3)
                        board[i][j] = 2;
                }
            }
        }
        // 第二遍遍历数组,将其中的2和3分别置1和0
        for(int i = 0; i < m; ++i) {
            for(int j = 0; j < n; ++j) {
                if(board[i][j] == 2)
                    board[i][j] = 1;
                if(board[i][j] == 3)
                    board[i][j] = 0;
            }
        }
    }
    
private:
    // 保存8个邻居的位置,方便进行邻居状态的判断
    int nei[8][2] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
};
原文地址:https://www.cnblogs.com/heyn1/p/11149801.html