这道题是LeetCode里的第289道题。

题目描述:

根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机。

给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞具有一个初始状态 live(1)即为活细胞, 或 dead(0)即为死细胞。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:

  1. 如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
  2. 如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
  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]
]

进阶:

  • 你可以使用原地算法解决本题吗?请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
  • 本题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?

不算难题,需要注意的点是更新要同时更新,不然会给结果带来影响,具体算法描述在代码中给出。

解题代码:

class Solution {
public:
void gameOfLife(vector<vector<int>>& board) {
if(board.size()==0||board[0].size()==0)return;
int m=board.size();int n=board[0].size();
int* NextTurnBoard=new int[m*n];//为了保证同时进行更新,这里新建一个地图
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
NextTurnBoard[i*n+j]=nextTurn(board,i,j);//同时执行下一回合
}
}
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
board[i][j]=NextTurnBoard[i*n+j];//更新地图
}
}
}
bool nextTurn(vector<vector<int>>&board,int r,int c){
int alivecount=0;
int m=board.size();int n=board[0].size();
for(int i=-1;i<=1;i++){
for(int j=-1;j<=1;j++){
if(r+i<0||r+i>m-1||c+j<0||c+j>n-1)continue;//边界处
else alivecount=alivecount+board[r+i][c+j];
}
}
alivecount=alivecount-board[r][c];//排除自身给结果带来的影响
if(alivecount<2||alivecount>3)return false;//死
else if(alivecount==3)return true;//活
else return board[r][c];//状态不变
}
};

提交结果:

个人总结:

原地算法涉及到最后的解,根据题目的意思:

  • alive < 2   live --> dead
  • alive = 2 or 3   live --> live
  • alive > 3   live --> dead
  • alive = 3   dead -->live

所以只有当周围活细胞数等于 3 时死细胞才会复活,对于活细胞来说当周围活细胞数小于 2 或 大于 3 时,活细胞会死亡。但是由于更新的结果不能给别的细胞带来影响,所以我们肯定不能在原来的面板上使用 0 或 1 更新细胞的状态。

void gameOfLife(vector<vector<int>>& board) {
int m = board.size(), n = board[0].size();
for(int i = 0; i < m; ++i){
for(int j = 0; j < n; ++j){
int lives = 0;
if(i > 0){//判断上边
lives += board[i-1][j] == 1 || board[i-1][j] == 2 ? 1:0;
}
if(i > 0 && j < n - 1){//判断右上角
lives += board[i-1][j+1] == 1 || board[i-1][j+1] == 2 ? 1:0;
}
if(j < n - 1){//判断右边
lives += board[i][j+1] == 1 || board[i][j+1] == 2 ? 1:0;
}
if(i < m - 1 && j < n - 1){//判断右下角
lives += board[i+1][j+1] == 1 || board[i+1][j+1] == 2 ? 1:0;
}
if(i < m - 1){//判断下边
lives += board[i+1][j] == 1 || board[i+1][j] == 2 ? 1:0;
}
if(i < m - 1 && j > 0){//判断左下角
lives += board[i+1][j-1] == 1 || board[i+1][j-1] == 2 ? 1:0;
}
if(j > 0){//判断左边
lives += board[i][j-1] == 1 || board[i][j-1] == 2 ? 1:0;
}
if(i > 0 && j > 0){//判断左上角
lives += board[i-1][j-1] == 1 || board[i-1][j-1] == 2 ? 1:0;
}
if(board[i][j] == 0 && lives == 3){// 更新
board[i][j] = 3;//dead->live
} else if(board[i][j] == 1){
if(lives < 2 || lives > 3){
board[i][j] = 2;//live->dead
}
}
}
}
for(int i = 0; i < m; ++i){// 解码
for(int j = 0; j < n; ++j){
board[i][j] = board[i][j] % 2;
}
}
}

这个问题以后值得在研究研究。

【LeetCode】Game of Life(生命游戏)的更多相关文章

  1. [LeetCode] Game of Life 生命游戏

    According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellul ...

  2. [Leetcode] 第289题 生命游戏

    一.题目描述 根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞.每个细胞具有一个初 ...

  3. [LeetCode] 289. Game of Life 生命游戏

    According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellul ...

  4. Leetcode 289.生命游戏

    生命游戏 根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞.每个细胞具有一个初始状 ...

  5. LeetCode | 289. 生命游戏(原地算法/位运算)

    记录dalao的位运算骚操作 根据百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细 ...

  6. Java实现 LeetCode 289 生命游戏

    289. 生命游戏 根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞.每个细胞具有 ...

  7. [Swift]LeetCode289. 生命游戏 | Game of Life

    According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellul ...

  8. React项目(二):生命游戏

    引子 这是16年最后的一个练手项目,一贯的感觉就是,做项目容易,写说明文档难.更何况是一个唤起抑郁感觉的项目,码下的每个字,心就如加了一个千斤的砝码. 2016年,有些事我都已忘记,但我现在还记得.2 ...

  9. 生命游戏/Game of Life的Java实现(转)

    首先简单介绍一下<生命游戏> 生命游戏其实是一个零玩家游戏.它包括一个二维矩形世界,这个世界中的每个方格居住着一个活着的或死了的细胞.一个细胞在下一个时刻生死取决于相邻八个方格中活着的或死 ...

随机推荐

  1. JS核心

    JS核心 1.实例化对象 objectName = new objectType (param1 [,param2] ...[,paramN]) 参数  objectName 新对象实例的名称. ob ...

  2. List 集合中数据不重复的使用

    foreach (DataRow dr in dt.Rows) { list.Add(dr["项目组"].ToString()); } list = list.Distinct&l ...

  3. nGrinder技术架构图

  4. JavaScript面试系列:JavaScript设计模式之桥接模式和懒加载

    我写的程序员面试系列文章 Java面试系列-webapp文件夹和WebContent文件夹的区别? 程序员面试系列:Spring MVC能响应HTTP请求的原因? Java程序员面试系列-什么是Jav ...

  5. Spring Boot配置文件大全

    Spring Boot配置文件大全 ############################################################# # mvc ############## ...

  6. 一个典型的flex布局,兼容性比较好

    html 代码: <body class="flex-wrap col-flex"> <header class="midCenter flex-wra ...

  7. haproxy文件的增删改查

    在构建一个程序项目之前,首先需要设计程序的框架,从总体上构建一个项目中的一个个功能,之后对每一个功能进行补充,最终实现总体的功能. 1 程序的总体框架: 首先把所有的功能设计成相应的函数,用pass来 ...

  8. oracle中group by的高级用法

    简单的group by用法 select c1,sum(c2) from t1 where t1<>'test' group by c1 having sum(c2)>100; ro ...

  9. 什么是二维数组?二维遍历?Java二维数组制作图片迷宫 使用如鹏游戏引擎制作窗口界面 附带压缩包下载,解压后双击start.bat启动

    什么是二维数组? 数组当中放的还是数组 int [][] arr=new int[3][2]; 有3个小箱子,每个箱子2个格子. 看结果? int [][] arr=new int[3][2]; Sy ...

  10. ios之自定义UINavigationBar

    ios5 自定义导航条问题 在ios5之前的系统中,可以通过定义导航条类别的方式自定义导航条: @implementation UINavigationBar (CustomImage)- (void ...