0x01.问题
根据 百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。
给定一个包含 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]
]
0x02.要点分析
读完题目,发现题目的思路很清晰,我们所需要做的事情是:
- 根据相应的规则,更新每个细胞的状态。
不过需要注意的是:
- 需要根据之前一轮的状态来更新状态,即本次更新,所有的细胞应该是同步更新的。
要解决这个问题,我们有两个思路:
- 思路一:使用一个数组来保存之前的状态。
- 思路二:原地赋予数组内容新的含义。
这里描述一下原地修改时赋予的新含义:
- 若之前活的,现在死了,变为-1.
- 若之前死的,现在活了,变为2.
最后再还原成用01表示的状态即可。
0x03.解决代码–新数组记录
class Solution {
public void gameOfLife(int[][] board) {
int step[]={0,1,-1};
int X=board.length;
int Y=board[0].length;
int[][] copy=new int[X][Y];
int x,y,i,j;
for(x=0;x<X;x++){
for(y=0;y<Y;y++){
copy[x][y]=board[x][y];
}
}
for(x=0;x<X;x++){
for(y=0;y<Y;y++){
int num=0;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
if(step[i]==0&&step[j]==0) continue;
int x1=x+step[i];
int y1=y+step[j];
if(x1<0||x1==X||y1<0||y1==Y) continue;
if(copy[x1][y1]!=1) continue;
num++;
}
}
if(copy[x][y]==1&&(num<2||num>3)){
board[x][y]=0;
}
if(copy[x][y]==0&&num==3){
board[x][y]=1;
}
}
}
return;
}
}
0x04.解决代码–原地修改
class Solution {
public void gameOfLife(int[][] board) {
int step[]={0,1,-1};
int X=board.length;
int Y=board[0].length;
int x,y,i,j;
for(x=0;x<X;x++){
for(y=0;y<Y;y++){
int num=0;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
if(step[i]==0&&step[j]==0) continue;
int x1=x+step[i];
int y1=y+step[j];
if(x1<0||x1==X||y1<0||y1==Y) continue;
if(Math.abs(board[x1][y1])!=1) continue;
num++;
}
}
if(board[x][y]==1&&(num<2||num>3)){
board[x][y]=-1;
}
if(board[x][y]==0&&num==3){
board[x][y]=2;
}
}
}
for(x=0;x<X;x++){
for(y=0;y<Y;y++){
if(board[x][y]<=0) board[x][y]=0;
else board[x][y]=1;
}
}
return;
}
}
Leetcode-4.2每日一题打卡完毕!
心情日记:加油哦~~
以后主要用java解决相关的算法题
ATFWUS --Writing By 2020–04-02