根据 百度百科 , 生命游戏 ,简称为 生命 ,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。
给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态: 1 即为 活细胞 (live),或 0 即为 死细胞 (dead)。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:
如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
如果死细胞周围正好有三个活细胞,则该位置死细胞复活;
下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是 同时 发生的。给你 m x n 网格面板 board 的当前状态,返回下一个状态。
给定当前 board 的状态,更新 board 到下一个状态。
注意 你不需要返回任何东西。
示例 1:
输入:board = [[0,1,0],[0,0,1],[1,1,1],[0,0,0]]
输出:[[0,0,0],[1,0,1],[0,1,1],[0,1,0]]
C++
class Solution {
public:
void gameOfLife(vector<vector<int>>& board) {
int x_index[]={-1,0,1,-1,1,-1,0,1};
int y_index[]={-1,-1,-1,0,0,1,1,1};
int rows=board.size();
int cols=board[0].size();
for( int i=0;i<rows;i++ ){
for( int j=0;j<cols;j++ ){
int sum=0;
for( int k=0;k<8;k++ ){
//确定当前矩阵中i,j元素周围8个位置的x,y坐标
int x=i+x_index[k];
int y=j+y_index[k];
if( x>=0 && x<rows && y>=0 && y<cols ){
//如果当前坐标为有效坐标
//原矩阵对应坐标的值为0(死亡)的情况:与运算(一假则假)
// 0 0
// 0 1
// 0 0
//原矩阵对应坐标的值为1(存活)的情况:与运算(一假则假)
// 0 1
// 0 1
// 0 1
sum+=(board[x][y]&1);//对当前坐标为i,j周围8个坐标元素值为1(存活)的进行求和
}
}
if( 1==board[i][j] ){
//当前坐标为i,j的元素值为1(存活)
if( 2==sum || 3==sum ){
//对当前坐标为i,j周围8个坐标元素值为1(存活)的总数为2个或者3个,依据规则当前元素存活
// 或运算(一真则真)
// 0 1
// 1 0
// 1 1
// 此时当前坐标为i,j的值为3
board[i][j] |=2;
}
}else{
//当前坐标为i,j的元素值为0(死亡)
if( 3==sum ){
//对当前坐标为i,j周围8个坐标元素值为1(存活)的总数刚好为3个,则该位置死细胞复活
// 或运算(一真则真)
// 0 0
// 1 0
// 1 0
// 此时当前坐标为i,j的值为2
board[i][j] |=2;
}
}
}
}
for( int i=0;i<rows;i++ ){
for( int j=0;j<cols;j++ ){
//经上述处理后,矩阵汇总元素的值有四种情况(0(0 0),1(0 1),2(1 0)(存活),3(1 1)(存活))
//位运算 右移 每向右移动一位相当于除以2
//0:
// 0 0
// 0 0
//右移一位结果为:0
//1:
// 0 1
// 0 0
//右移一位结果为:0
//2:
// 1 0
// 0 1
//右移一位结果为:1
//3:
// 1 1
// 0 1
//右移一位结果为:1
board[i][j]>>=1;
}
}
}
};
时间复杂度
O ( M ∗ N ) O(M*N) O(M∗N)
空间复杂度
O ( 1 ) O(1) O(1)
Java
class Solution {
public void gameOfLife(int[][] board) {
int x_index []={-1,0,1,-1,1,-1,0,1};
int y_index []={-1,-1,-1,0,0,1,1,1};
int rows=board.length;
int cols=board[0].length;
for( int i=0;i<rows;i++ ){
for( int j=0;j<cols;j++ ){
int sum=0;
for( int k=0;k<8;k++ ){
int x=i+x_index[k];
int y=j+y_index[k];
if( x>=0 && x<rows && y>=0 && y<cols ){
sum+=(board[x][y]&1);
}
}
if( 1==board[i][j] ){
if( 2==sum || 3==sum ){
board[i][j]|=2;
}
}else{
if( 3==sum ){
board[i][j]|=2;
}
}
}
}
for( int i=0;i<rows;i++ ){
for( int j=0;j<cols;j++ ){
board[i][j]>>=1;
}
}
}
}
时间复杂度
O ( M ∗ N ) O(M*N) O(M∗N)
空间复杂度
O ( 1 ) O(1) O(1)
Python
class Solution:
def gameOfLife(self, board: List[List[int]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
x_index=[-1,0,1,-1,1,-1,0,1];
y_index=[-1,-1,-1,0,0,1,1,1];
rows=len(board);
cols=len(board[0]);
for i in range(rows):
for j in range(cols):
sum=0;
for k in range(8):
x=i+x_index[k];
y=j+y_index[k];
if x>=0 and x<rows and y>=0 and y<cols:
sum=sum +(1 & board[x][y]);
if 1==board[i][j]:
if 2==sum or 3==sum:
board[i][j]=board[i][j]|2;
else:
if 3==sum:
board[i][j]=board[i][j]|2;
for i in range(rows):
for j in range(cols):
board[i][j]=board[i][j]>>1;
时间复杂度
O ( M ∗ N ) O(M*N) O(M∗N)
空间复杂度
O ( 1 ) O(1) O(1)