这道题是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. React 实践记录 02 Flux introduction

    Introduction 本文组成: React 官方文档翻译 相关实践心得. 内容上是Flux的介绍,例子将会在以后写出. 一旦稍微多了解一点React,很难避免听到Flux这个名词. Flux是一 ...

  2. JAVA 时间的使用

    今天老师又没有讲新课,不过讲了练习题,扩展了一下我们的思维. 今天就讲一下如何获取时间吧. 代码: import java.util.* public class Test{ public stati ...

  3. ubuntu下安装无线网卡去驱动Qualcomm-Atheros-QCA9377

    文件(文档和压缩包):http://pan.baidu.com/s/1mhktFT2

  4. hdoj薛猫猫杯程序设计网络赛1003 球球大作战

    思路: 二分,check函数不是很好写. 实现: 1. #include <bits/stdc++.h> using namespace std; typedef long long ll ...

  5. 能挣钱的微信JSSDK+H5混合开发

    H5喊了那么久,有些人都说不实用,有些人却利用在微信中开发H5应用赚得盆满钵满.微信JSSDK + HTML 5,让移动Web开发与微信结合轻而易举!跨平台.零成本,让大众创业变得更方便. 我觉得现在 ...

  6. 【NumPy学习指南】day5 改变数组的维度

    我们已经学习了怎样使用reshape函数,现在来学习一下怎样将数组展平. (1) ravel 我们可以用ravel函数完成展平的操作: In: b Out: array([[[ 0, 1, 2, 3] ...

  7. codeforces Gym 100338C Important Roads (重建最短路图)

    正反两次最短路用于判断边是不是最短路上的边,把最短路径上的边取出来建图.然后求割边.注意重边,和卡spfa. 正权,好好的dijkstra不用,用什么spfa? #include<bits/st ...

  8. IOS音频视频

    视频播放 MediaPlayer.framework MPMoviePlayerViewController VS MPMoviePlayerController MPMoviePlayerViewC ...

  9. 爬虫_python3_抓取猫眼电影top100

    使用urllib,request,和正则表达式,多线程进行秒抓,以及异常处理结果: import urllib,re,json from multiprocessing import Pool#多进程 ...

  10. CPP-基础:友元

    友元可以是一个函数,该函数被称为友元函数:友元也可以是一个类,该类被称为友元类. 我们已知道类具有封装和信息隐藏的特性.只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的.非成 ...