题目:

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. Liunx0000(初步认识)

    都要放假了,学习一下吧,毕竟还有课设,虽然我真的懒得看Linux,不想接触这破玩意!各应人的东西! 一.发展趋势 1\无操作系统阶段20s60 2\简单操作系统阶段 3\试试操作系统阶段 4\面向In ...

  2. vs2013中使用nuget下载cefsharp winform包

    cefsharp是chrome的一个开源项目,基于webkit的一个浏览器.下载cefsharp需要安装nuget.之后管理nuget程序包,联机搜索cef即可找到winform包.

  3. linux查看有哪些shell可用

    1.命令cat /etc/shells [tansheng@localhost ~]$ cat /etc/shells /bin/sh /bin/bash /sbin/nologin /bin/das ...

  4. 容器适配器之priority_queue

    template <class T, class Container = vector<T>,                class Compare = less<type ...

  5. 课堂练习:给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数。

    题目 1 给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数. 2 要求: (1) 写一个函数 f(N) ,返回1 到 N 之间出现的“1”的个数.例如 f(12)  ...

  6. Java面试之SE基础基本数据类型

    1.九种基本数据类型的大小以及它们的封装类 在我们面试或者考试过程中经常会考到八种基本数据类型以及它们的封装类,那么有哪八种基本数据类型呢?它们的封装类又是什么呢? 首先,八种基本数据类型分别是:in ...

  7. jquery动态加载JS【方法getScript】的改进

    http://www.cnblogs.com/cuitsl/archive/2012/11/15/2771549.html

  8. VIM 技巧 (一)全文统一添加

    大家应该有遇到过给整篇内容增加同样的东西的经历.例如给每行结尾增加分号.冒号等内容. 今天和大家分享下 关于此场景如何快速.高效的实现. 例如 Line one Line two Line three ...

  9. 2014ACM/ICPC亚洲区鞍山站 清华命题

    A http://acm.hdu.edu.cn/showproblem.php?pid=5070 先跳过. B http://acm.hdu.edu.cn/showproblem.php?pid=50 ...

  10. 我收集到的最好的jQuery和CSS3导航菜单

    jQuery和CSS3导航菜单在网页设计和开发的重要组成部分之一.利用jQuery+CSS3实现可以做出拥有各种动画效果的漂亮菜单.在这里,我们收集了一些最好的jQuery+CSS3实现的导航菜单. ...