[LeetCode]289. Game of Life
Medium
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):
- 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.
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.
Example:
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]
]
Follow up:
- Could you solve it in-place? Remember that the board needs to be updated at the same time: You cannot update some cells first and then use their updated values to update other cells.
- In this question, we represent the board using a 2D array. In principle, the board is infinite, which would cause problems when the active area encroaches the border of the array. How would you address these problems?
题目大意:
用2维数组表示生存在一起的细胞群,每个细胞有8个邻居,上、下、左、右、上左、上右、下左、下右。他们每个一段时间就会更新一次生存状态,0为死亡,1为活:
1.当一个细胞邻居少于2个时,这个细胞会死(孤独死)
2.当邻居多于2,但小于3时,这个细胞不会变化
3.当邻居为3个时,这个细胞会复活
4.当邻居多于3个时,这个细胞会死(拥挤死)
细胞的生存状态会统一进行更新,不能使用一个细胞更新后的状态来更新别的细胞生存状态。
方法:
因为题目要求在原数组上对细胞生存状态进行更新,所以我们采用对需要改变状态的单元格进行标记,最后统一更新单元格状态的方法。先定义一个方法用于统计一个细胞的邻居存活数,当一个细胞的状态为0,且要在下次更新为1时,我们将其标识为-1,当一个细胞状态为1,且将要更新为0时,我们将其标识为2,这样最后我们只要遍历数组将-1变为1,2变为0就好了。为什么采用-1和2来进行标识呢?因为我们必需保证对比过程中细胞的状态判断。用是否大于0来判断细胞的生存状态,那么使用-1和2就可以维持当前的细胞生存状态了。
代码如下:
C++
/*** C++ ***/ class Solution { public: void gameOfLife(vector<vector<int>>& board) { if(board.size()==0 || board[0].size()==0)return; int m=board.size(),n=board[0].size(); for(int i=0;i<m;++i){ for(int j=0;j<n;++j){ int n = helper(board, i, j); if(n<2 || n>3){ board[i][j]=board[i][j]==0?board[i][j]:2; } if(n==3){ board[i][j]=board[i][j]==0?-1:board[i][j]; } } } for(int i=0;i<m;++i){ for(int j=0;j<n;++j){ board[i][j]=board[i][j]<0?-board[i][j]%2:board[i][j]%2; } } return; } int helper(vector<vector<int>>& board, int i, int j){ int res=0; int m=board.size(),n=board[0].size(); if(i>0 && j>0 && board[i-1][j-1]>0)res++; if(i>0 && board[i-1][j]>0)res++; if(i>0 && j<n-1 && board[i-1][j+1]>0)res++; if(j>0 && board[i][j-1]>0)res++; if(j<n-1 && board[i][j+1]>0)res++; if(i<m-1 && j>0 && board[i+1][j-1]>0)res++; if(i<m-1 && board[i+1][j]>0)res++; if(i<m-1 && j<n-1 && board[i+1][j+1]>0)res++; return res; } };