【LeetCode】Game of Life(生命游戏)
这道题是LeetCode里的第289道题。
题目描述:
根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机。
给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞具有一个初始状态 live(1)即为活细胞, 或 dead(0)即为死细胞。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:
- 如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
- 如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
- 如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
- 如果死细胞周围正好有三个活细胞,则该位置死细胞复活;
根据当前状态,写一个函数来计算面板上细胞的下一个(一次更新后的)状态。下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是同时发生的。
示例:
输入:
[
[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(生命游戏)的更多相关文章
- [LeetCode] Game of Life 生命游戏
According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellul ...
- [Leetcode] 第289题 生命游戏
一.题目描述 根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞.每个细胞具有一个初 ...
- [LeetCode] 289. Game of Life 生命游戏
According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellul ...
- Leetcode 289.生命游戏
生命游戏 根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞.每个细胞具有一个初始状 ...
- LeetCode | 289. 生命游戏(原地算法/位运算)
记录dalao的位运算骚操作 根据百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细 ...
- Java实现 LeetCode 289 生命游戏
289. 生命游戏 根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞.每个细胞具有 ...
- [Swift]LeetCode289. 生命游戏 | Game of Life
According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellul ...
- React项目(二):生命游戏
引子 这是16年最后的一个练手项目,一贯的感觉就是,做项目容易,写说明文档难.更何况是一个唤起抑郁感觉的项目,码下的每个字,心就如加了一个千斤的砝码. 2016年,有些事我都已忘记,但我现在还记得.2 ...
- 生命游戏/Game of Life的Java实现(转)
首先简单介绍一下<生命游戏> 生命游戏其实是一个零玩家游戏.它包括一个二维矩形世界,这个世界中的每个方格居住着一个活着的或死了的细胞.一个细胞在下一个时刻生死取决于相邻八个方格中活着的或死 ...
随机推荐
- 蜥蜴-DInic
题目背景 07四川省选 题目描述 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴 ...
- 本机运行x程序出现:Can't open display 原因及其解决方法(貌似非永久)
http://blog.sina.com.cn/s/blog_53db572501016ma7.html 这是因为Xserver默认情况下不允许别的用户的图形程序的图形显示在当前屏幕上. 如果需要别的 ...
- react项目构建中的坑—淘宝镜像安装后要设置
基本的搭建步骤参考博客:https://blog.csdn.net/qq_27727251/article/details/86593415 这里要强调的坑是:安装完淘宝镜像要将其设置为默认Regis ...
- FreeMusic项目优化(一)——flex布局学习记录
参考博客:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html flex布局是w3c于09年提出的,用于简便,整洁,响应式地解决布局问题的手 ...
- 【cpp】new delete
double *M = new double[2*num]; double *T = new double[2 * num]; double *activeM = new double[2 * num ...
- 【排序】插入排序:最稳定:时间复杂度O(n^2)
想象着自己在玩扑克的时候抓牌,每抓到一张牌,按照从小到大的顺序排序. 如果第二张的点数小于第一张,就交换这两张牌,默认每次抓牌之前,前面的已经排好序了. 再来一张牌,与第二张比较,如果小于第二张,交换 ...
- Android学习总结(十八) ———— SQLite数据库使用
一.基本概念 数据库最经典的四个操作 添加.删除.修改.查找,在处理大量数据的时候使用数据库可以帮我们迅速定位当前须要处理的数据,举个例子 好比现在要实现一个搜索功能 用数据库的话只须要其中一个搜索条 ...
- 洛谷 P2947 [USACO09MAR]仰望Look Up
题目描述 Farmer John's N (1 <= N <= 100,000) cows, conveniently numbered 1..N, are once again stan ...
- OpenCV2:介绍
一.OpenCV简介 OpenCV所有的类和函数都在cv命名空间里面,可以用 using namespace cv; #include "opencv2/opencv.hpp" 1 ...
- Java8新特性Lambda表达式
List<RoleDO> allRoles = roleService.list(); //获取角色中备注不是app的集合List<RoleDO> webRoles = all ...