289. Game of Life
题目:
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):
- Any live cell with fewer than two live neighbors dies, as if caused by under-population.
- Any live cell with two or three live neighbors lives on to the next generation.
- Any live cell with more than three live neighbors dies, as if by over-population..
- 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:
- 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.
- 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的更多相关文章
- leetcode@ [289] Game of Life (Array)
https://leetcode.com/problems/game-of-life/ According to the Wikipedia's article: "The Game of ...
- SCUT - 289 - 小O的数字 - 数位dp
https://scut.online/p/289 一个水到飞起的模板数位dp. #include<bits/stdc++.h> using namespace std; typedef ...
- 2017-3-9 leetcode 283 287 289
今天操作系统课,没能安心睡懒觉23333,妹抖龙更新,可惜感觉水分不少....怀念追RE0的感觉 =================================================== ...
- [LeetCode] 289. Game of Life 生命游戏
According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellul ...
- Java实现 LeetCode 289 生命游戏
289. 生命游戏 根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞.每个细胞具有 ...
- 289. Game of Life -- In-place计算游戏的下一个状态
According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellul ...
- nyoj 289 苹果 动态规划 (java)
分析:0-1背包问题 第一次写了一大串, 时间:576 内存:4152 看了牛的代码后,恍然大悟:看来我现在还正处于鸟的阶段! 第一次代码: #include<stdio.h> #inc ...
- 贪心 Codeforces Round #289 (Div. 2, ACM ICPC Rules) B. Painting Pebbles
题目传送门 /* 题意:有 n 个piles,第 i 个 piles有 ai 个pebbles,用 k 种颜色去填充所有存在的pebbles, 使得任意两个piles,用颜色c填充的pebbles数量 ...
- 递推水题 Codeforces Round #289 (Div. 2, ACM ICPC Rules) A. Maximum in Table
题目传送门 /* 模拟递推水题 */ #include <cstdio> #include <iostream> #include <cmath> #include ...
- 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 ...
随机推荐
- NABC的特点分析
题目: 请把采用卡片分类的方法讨论你们的团队开发项目特点,再按照 NABC 的框架分析每个特点. 每一个组员针对其中的一个特点将NABC的分析结果发表博 ...
- C#委托详解(3):委托的实现方式大全(续)
接上篇(C#委托详解(2):实现方式大全),本篇继续介绍委托的实现方式. 4.Action<T>和Func<T>委托 使用委托时,除了为每个参数和返回类型定义一个新委托类型之外 ...
- 自动回复消息-微信公众平台开发4(asp.net)
接着上一节的processRequest 处理函数,代码如下: /// <summary> /// 处理微信发来的请求 /// </summary> /// ...
- Chapter 3 Discovering Classes and Object
Chatper 3 Discovering Classes and Object Exercises: 1.What is a class? A class is a template for man ...
- Using sql azure for Elmah
The MSDN docs contain the list of T-SQL that is either partially supported or not supported. For ex ...
- 2014ACM/ICPC亚洲区西安站 复旦命题
http://codeforces.com/gym/100548 A 签到 问一个序列是不是yes,yes的序列满足每个数都是3的倍数. #include<cstdio> int main ...
- 2010 Asia Fuzhou Regional Contest
A hard Aoshu Problem http://acm.hdu.edu.cn/showproblem.php?pid=3699 用深搜写排列,除法要注意,还有不能有前导零.当然可以5个for, ...
- js中常用数组方法concat join push pop slice splice shift
javascript给我们很多常用的 数组方法,极大方便了我们做程序.下面我们来介绍下常用的集中数组方法. 比如 concat() join() push() pop() unshift() shif ...
- 负MARGIN之讲解
css中的负边距(negative margin)是布局中的一个常用技巧,只要运用得合理常常会有意想不到的效果.很多特殊的css布局方法都依赖于负边距,所以掌握它的用法对于前端的同学来说,那是必须的. ...
- CSRF攻击之原理讲解
|=——————————————————————=| |=————–=[ CSRF攻击原理解析 ]=——————=| |=——————————————————————=| |=——————-=[ By ...