According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970."

Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article):

  1. Any live cell with fewer than two live neighbors dies, as if caused by under-population.
  2. Any live cell with two or three live neighbors lives on to the next generation.
  3. Any live cell with more than three live neighbors dies, as if by over-population..
  4. Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.

Write a function to compute the next state (after one update) of the board given its current state.

Follow up:

  1. Could you solve it in-place? Remember that the board needs to be updated at the same time: You cannot update some cells first and then use their updated values to update other cells.
  2. In this question, we represent the board using a 2D array. In principle, the board is infinite, which would cause problems when the active area encroaches the border of the array. How would you address these problems?

【题目分析】

题目中一个细胞的生死是由他的邻居细胞中活细胞的数目确定的,他的邻居细胞位于上,下,左,右,左上,右上,左下,右下。规则如下:

1. 一个活细胞的邻居中如果活着的细胞少于两个,那么该细胞将会死亡;

2. 一个活细胞的邻居中如果活着的细胞等于两个或三个,那么该细胞将会存活;

3. 一个活细胞的邻居中如果活着的细胞多于三个,那么该细胞将会死亡;

4. 一个死细胞的邻居中如果活着的细胞等于三个,那么该细胞将会复活;

用一个0,1二维数组表示细胞的相对位置,0表示该位置的细胞死亡,1表示该位置细胞活着。更新细胞的状态,就地完成,不适用额外的存储空间。


【思路】

1. 该问题的难点在于就地完成,不使用额外的存储空间。在本题目中一个细胞状态变化后不能马上修改数组的内容,否则的话他的邻居细胞在统计他活着的邻居细胞时候数目将会是不正确的。我们必须把所有细胞的状态变化情况求出来,才能统一对细胞的状态进行改变。如何实现呢?

细胞的状态变化有两种情况1->0和0->1,我们设置两个标记,如果是1->0,我们把该位置赋值为-1,如果是0->1,我们把该细胞位置赋值为2。这样的话我们既保存了细胞的原始状态信息,也保存了细胞的变化情况。遍历每一个细胞,我们得到了所有细胞的变化情况,然后再次遍历数组,把所有-1变为0,所有2变为1即可。

2. 一个巧妙的思路如下:


【java代码1】

 public class Solution {
public void gameOfLife(int[][] board) {
if(board == null || board.length == 0 || board[0].length == 0) return;
int row = board.length;
int col = board[0].length; for(int i = 0; i < row; i++){ //第一次遍历,求出每一个细胞的状态变化情况
for(int j = 0; j < col; j++){
int num = neightbors(board, i, j);
if(board[i][j] == 1 && (num < 2 || num > 3))
board[i][j] = -1;
else if(board[i][j] == 0 && num == 3)
board[i][j] = 2;
else ;
}
} for(int i = 0; i < row; i++){ //第二次遍历修改细胞的状态
for(int j = 0; j < col; j++){
if(board[i][j] == -1)
board[i][j] = 0;
else if(board[i][j] == 2)
board[i][j] = 1;
else ;
}
}
} public int neightbors(int[][] board, int i, int j){ //求某个细胞的活着的邻居数目
int left = Math.max(0, j-1);
int right = Math.min(j+1, board[0].length-1);
int top = Math.max(i-1, 0);
int button = Math.min(i+1, board.length-1); int sum = 0;
for(int k = top; k <= button; k++){
for(int t = left; t <= right; t++){
if(board[k][t] == 1 || board[k][t] == -1) sum ++;
}
}
return board[i][j] == 0? sum : sum - 1;
}
}

【java代码2】

 public void gameOfLife(int[][] board) {
if(board == null || board.length == 0) return;
int m = board.length, n = board[0].length; for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
int lives = liveNeighbors(board, m, n, i, j); // In the beginning, every 2nd bit is 0;
// So we only need to care about when the 2nd bit will become 1.
if(board[i][j] == 1 && lives >= 2 && lives <= 3) {
board[i][j] = 3; // Make the 2nd bit 1: 01 ---> 11
}
if(board[i][j] == 0 && lives == 3) {
board[i][j] = 2; // Make the 2nd bit 1: 00 ---> 10
}
}
} for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
board[i][j] >>= 1; // Get the 2nd state.
}
}
} public int liveNeighbors(int[][] board, int m, int n, int i, int j) {
int lives = 0;
for(int x = Math.max(i - 1, 0); x <= Math.min(i + 1, m - 1); x++) {
for(int y = Math.max(j - 1, 0); y <= Math.min(j + 1, n - 1); y++) {
lives += board[x][y] & 1;
}
}
lives -= board[i][j] & 1;
return lives;
}

LeetCode OJ 289. Game of Life的更多相关文章

  1. LeetCode OJ 题解

    博客搬至blog.csgrandeur.com,cnblogs不再更新. 新的题解会更新在新博客:http://blog.csgrandeur.com/2014/01/15/LeetCode-OJ-S ...

  2. 【LeetCode OJ】Interleaving String

    Problem Link: http://oj.leetcode.com/problems/interleaving-string/ Given s1, s2, s3, find whether s3 ...

  3. 【LeetCode OJ】Reverse Words in a String

    Problem link: http://oj.leetcode.com/problems/reverse-words-in-a-string/ Given an input string, reve ...

  4. LeetCode OJ学习

    一直没有系统地学习过算法,不过算法确实是需要系统学习的.大二上学期,在导师的建议下开始学习数据结构,零零散散的一学期,有了链表.栈.队列.树.图等的概念.又看了下那几个经典的算法——贪心算法.分治算法 ...

  5. LeetCode OJ 297. Serialize and Deserialize Binary Tree

    Serialization is the process of converting a data structure or object into a sequence of bits so tha ...

  6. 备份LeetCode OJ自己编写的代码

    常泡LC的朋友知道LC是不提供代码打包下载的,不像一般的OJ,可是我不备份代码就感觉不舒服- 其实我想说的是- 我自己写了抓取个人提交代码的小工具,放在GitCafe上了- 不知道大家有没有兴趣 ht ...

  7. LeetCode OJ 之 Maximal Square (最大的正方形)

    题目: Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and ...

  8. LeetCode OJ:Integer to Roman(转换整数到罗马字符)

    Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 t ...

  9. LeetCode OJ:Serialize and Deserialize Binary Tree(对树序列化以及解序列化)

    Serialization is the process of converting a data structure or object into a sequence of bits so tha ...

随机推荐

  1. 隐藏android中EditText中的下划线以及修改光标颜色

    在android开发中 EditTextText是我们经常用到的,我们使用时会有一些小问题,当我们点击输入文字时,EditText中的光标和下划线会变成粉红色. 解决方法很简单,我们只要在EditTe ...

  2. 开学&东大一周游记

    明天就要离开生活但并没有学到多少东西的东大了,不舍,这是真的,因为真的是没学到多少就要走了.但是终归是有收获的,比如感受到了舍长这样的大牛的学习态度,东大的浴池真的很棒,我很感激吉大的伙食诸如此类.感 ...

  3. angular-ui-bootstrap插件API - Pager

    Pager: 案例 <!DOCTYPE html> <html lang="en" ng-app="myApp"> <head&g ...

  4. javascript入门基础知识

    JavaScript介绍: 1. javascrip是互联网上最流行的脚本语言,可用于Web和HTML,更可广泛用于服务器.pc端.移动端. 2. javascript脚本语言: javascript ...

  5. wpf 界面线程 添加项

    foreach (var r in sec.Records) { listView.Dispatcher.Invoke((new Action(delegate() { listView.Items. ...

  6. ansible module

    模块是一个独立的, 可以复用的脚本, 它可以被anisible API, Ansible 或者ansible-playbook使用.   在模块退出之前, 它通过输出一个json字符串到标准输出从而反 ...

  7. Hadoop优先级调度

    当同时在集群中运行多个作业时,默认情况下,Hadoop将提交的作业放入一个FIFO,一个作业结束后,Hadoop就启动下一个作业. 当一个运行时间长但是优先级较低的作业先于运行时间短而优先级较高的作业 ...

  8. inux按照CPU、内存、磁盘IO、网络性能监测

    http://my.oschina.net/chape/blog/159640 系统优化是一项复杂.繁琐.长期的工作,优化前需要监测.采集.测试.评估,优化后也需要测试.采集.评估.监测,而且是一个长 ...

  9. Spring Security(19)——对Acl的支持

    目录 1.1           准备工作 1.2           表功能介绍 1.2.1     表acl_sid 1.2.2     表acl_class 1.2.3     表acl_obj ...

  10. Gulp安装使用教程

    题记:为什么要使用gulp,网上有很多关于gulp的优势,而在我看来,这些都是工具的优势!工具的优势最主要体现在易用性上,听说gulp比grunt更易用,所以这里写个文档记录. 同样要保证nodejs ...