题目:

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?

链接: http://leetcode.com/problems/game-of-life/

题解:

生命游戏。题目比较长,用extra array做的话比较简单,但要求in-place的话,我们就要使用一些技巧。这里的方法来自yavinci,他的很多Java解法都既精妙又易读,真的很厉害。 我们用两个bit位来代表当前回合和下回合的board。

00代表当前dead

01代表当前live, next dead

10代表当前dead,next live

11代表当前和next都是live

按照题意对当前cell进行更新,全部更新完毕以后, 需要再遍历一遍整个数组,将board upgrade到下一回合, 就是每个cell >>= 1。

Time Complexity - O(mn), Space Complexity - O(1)。

public class Solution {
public void gameOfLife(int[][] board) {
if(board == null || board.length == 0) {
return;
} for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[0].length; j++) {
int liveNeighbors = getLiveNeighbors(board, i, j);
if((board[i][j] & 1) == 1) {
if(liveNeighbors >= 2 && liveNeighbors <= 3) {
board[i][j] = 3; // change to "11", still live
} // else it stays as "01", which will be eleminated next upgrade
} else {
if(liveNeighbors == 3) {
board[i][j] = 2; // change to "10", become live
}
}
}
} for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[0].length; j++) {
board[i][j] >>= 1;
}
}
} private int getLiveNeighbors(int[][] board, int row, int col) {
int res = 0;
for(int i = Math.max(row - 1, 0); i <= Math.min(board.length - 1, row + 1); i++) {
for(int j = Math.max(col - 1, 0); j <= Math.min(board[0].length - 1, col + 1); j++) {
res += board[i][j] & 1;
}
}
res -= board[row][col] & 1;
return res;
}
}

二刷:

稍微简写了一下。

Java:

public class Solution {
private int[][] directions = new int[][] {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, 0}, {1, -1}, {1, 1}}; public void gameOfLife(int[][] board) {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
int sum = 0;
for (int[] direction : directions) {
int row = i + direction[0];
int col = j + direction[1];
if (row < 0 || col < 0 || row > board.length - 1 || col > board[0].length - 1) {
continue;
}
if ((board[row][col] & 1) == 1) {
sum++;
}
}
if (board[i][j] == 1 && (sum == 2 || sum == 3)) {
board[i][j] = 3;
} else if (sum == 3) {
board[i][j] = 2; //
}
}
} for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
board[i][j] >>= 1;
}
}
}
}

三刷:

和上述一样的方法,就是写。

Java:

public class Solution {
public void gameOfLife(int[][] board) {
if (board == null || board.length == 0) return;
int rowNum = board.length, colNum = board[0].length; for (int i = 0; i < rowNum; i++) {
for (int j = 0; j < colNum; j++) {
int count = getNeighborLiveCells(board, i, j);
if (board[i][j] == 1) {
if (count == 2 || count == 3) board[i][j] = 3;
} else {
if (count == 3) board[i][j] = 2;
}
}
} for (int i = 0; i < rowNum; i++) {
for (int j = 0; j < colNum; j++) {
board[i][j] >>= 1;
}
}
} private int getNeighborLiveCells(int[][] board, int row, int col) {
int count = 0;
for (int i = row - 1; i <= row + 1; i++) {
for (int j = col - 1; j <= col + 1; j++) {
if (i < 0 || j < 0 || i > board.length - 1 || j > board[0].length - 1|| (i == row && j == col)) continue;
if ((board[i][j] & 1) == 1) count++;
}
}
return count;
}
}

Reference:

https://leetcode.com/discuss/68352/easiest-java-solution-with-explanation

https://leetcode.com/discuss/61912/c-o-1-space-o-mn-time

https://leetcode.com/discuss/61910/clean-o-1-space-o-mn-time-java-solution

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

  1. leetcode@ [289] Game of Life (Array)

    https://leetcode.com/problems/game-of-life/ According to the Wikipedia's article: "The Game of ...

  2. SCUT - 289 - 小O的数字 - 数位dp

    https://scut.online/p/289 一个水到飞起的模板数位dp. #include<bits/stdc++.h> using namespace std; typedef ...

  3. 2017-3-9 leetcode 283 287 289

    今天操作系统课,没能安心睡懒觉23333,妹抖龙更新,可惜感觉水分不少....怀念追RE0的感觉 =================================================== ...

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

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

  5. Java实现 LeetCode 289 生命游戏

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

  6. 289. Game of Life -- In-place计算游戏的下一个状态

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

  7. nyoj 289 苹果 动态规划 (java)

    分析:0-1背包问题 第一次写了一大串, 时间:576  内存:4152 看了牛的代码后,恍然大悟:看来我现在还正处于鸟的阶段! 第一次代码: #include<stdio.h> #inc ...

  8. 贪心 Codeforces Round #289 (Div. 2, ACM ICPC Rules) B. Painting Pebbles

    题目传送门 /* 题意:有 n 个piles,第 i 个 piles有 ai 个pebbles,用 k 种颜色去填充所有存在的pebbles, 使得任意两个piles,用颜色c填充的pebbles数量 ...

  9. 递推水题 Codeforces Round #289 (Div. 2, ACM ICPC Rules) A. Maximum in Table

    题目传送门 /* 模拟递推水题 */ #include <cstdio> #include <iostream> #include <cmath> #include ...

  10. NYOJ-289 苹果 289 AC(01背包) 分类: NYOJ 2014-01-01 21:30 178人阅读 评论(0) 收藏

    #include<stdio.h> #include<string.h> #define max(x,y) x>y?x:y struct apple { int c; i ...

随机推荐

  1. 关于网站IIS日志分析搜索引擎爬虫说明

    正文:iis默认的日志文件在C:\WINDOWS\system32\LogFiles中,下面是Seoer惜缘的服务器日志,通过查看,就可以了解搜索引擎蜘蛛爬行经过,如: 2008-08-19 00:0 ...

  2. 6、android开发中遇到的bug整理

    1.使用actionProvider时出现的问题 bug复现: 解决方案: //import android.support.v4.view.ActionProvider; import androi ...

  3. httphelp web自动化

    public class HttpHelper    {        public static CookieContainer CookieContainers = new CookieConta ...

  4. 【转】GCC编译使用动态链接库

    相关gcc参数:-l -L -shared -fPIC -static -c -o   原文地址:[脚本之家]http://www.jb51.net/article/34990.htm     根据链 ...

  5. 记codevs第一次月赛

    第一次参加这种有奖励的比赛(没错,我就是为猴子而去的 一年没怎么碰代码果然手生,还是用没写多久的C++,差点全跪了 T1数学奇才琪露诺: 首先定义一个函数F(x),F(x)=x的各个数位上的数字和 然 ...

  6. 【POJ】【1635】Subway Tree Systems

    树的最小表示法 给定两个有根树的dfs序,问这两棵树是否同构 题解:http://blog.sina.com.cn/s/blog_a4c6b95201017tlz.html 题目要求判断两棵树是否是同 ...

  7. LAMP一键安装包-CentOS 5/6下自动编译安装Apache,MySQL,PHP

    http://www.centos.bz/lamp/ 此安装包已经不再维护,请使用新版http://www.centos.bz/ezhttp/. 适用环境: 系统支持:CentOS-5 (32bit/ ...

  8. CSRF(跨站请求伪造)攻击方式

    一.CSRF是什么? CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSR ...

  9. Effeckt.css项目:CSS交互动画应用集锦

    目前,网上有大量基于CSS转换的实验和示例,但它们都过于分散,而Effeckt.css的目标就是把所有基于CSS/jQuery动画的应用集中起来,例如:弹窗.按钮.导航.列表.页面切换等等. Effe ...

  10. MVC模式在游戏开发的应用

    原地址: http://www.cocoachina.com/gamedev/2012/1129/5212.html MVC是三个单词的缩写,分别为:模型(Model).视图(View)和控制Cont ...