题目:

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. 仿照CREATE_FUNC实现CCLayer中的返回CCScene* 的静态函数,宏包装成CREATE_SCENE(XXLayer)

    #define CREATE_SCENE(__TYPE__)\ CCScene *scene()\ { CCScene *scene=CCScene::create();\ __TYPE__ *lay ...

  2. zabbix语言设置

    1.怎样支持中文: https://www.zabbix.org/wiki/How_to/install_locale 官方解决方法 实际操作中,进入/var/lib/locales/supporte ...

  3. MVC5 + EF6 入门完整教程 (1)

    第0课 从0开始 ASP.NET MVC开发模式和传统的WebForm开发模式相比,增加了很多"约定". 直接讲这些 "约定" 会让人困惑,而且东西太多容易忘记 ...

  4. 04.spring-data-redis与Jedis整合使用

    1.spring-data-redis与Jedis简单整合 spring-data-redis与Jedis简单整合,Redis没有任何集群只是单节点工作,使用连接池 1.创建spring-contex ...

  5. JS 数组的基础知识

    数组 一.定义 1.数组的文字定义 广义上说,数组是相同类型数据的集合.但是对于强类型语言和弱类型语言来说其特点是不一样的.强类型语言数组和集合有以下特点. 数组强类型语言:1.数组里面只能存放相同数 ...

  6. IOS-闪光灯操作

    AVCaptureDevice.h主要用来获取iphone一些关于相机设备的属性. 前置和后置摄像头 enum { AVCaptureDevicePositionBack = , AVCaptureD ...

  7. ASP.NET页面刷新的实现方法总结

    先看看ASP.NET页面刷新的实现方法: 第一: private void Button1_Click( object sender, System.EventArgs e ) { Response. ...

  8. TKStudio 4.6IDE Warning: L6310W: Unable to find ARM libraries.

    我也遇到了同样的问题.搞了很久,按下面的操解决了 内容转至:http://bbs.zlgmcu.com/dv_rss.asp?s=xh&boardid=43&id=23032& ...

  9. linux gcc loudong

    五事九思 (大连Linux主机维护) 大连linux维护qq群:287800525 首页 日志 相册 音乐 收藏 博友 关于我     日志       spcark_0.0.3_i386.src.t ...

  10. Ruby中的Profiling工具

    看看如何调试Ruby的性能问题 李哲 - APRIL 08, 2015 Ruby内置的profiler 内置的profiler实现的很简单,在ruby2.2中只有150行代码,大家可以看看它的实现pr ...