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 ...
随机推荐
- 结队开发项目——基于Android的无线点餐系统——NABC模型
特点:通过提前订餐,可以节约学生大量的排队时间. N(need):生活中可以发现许多同学都喜欢出去买饭,而且在有的摊位需要排很长时间的队,这样他们就会很晚吃到饭,下午有课的学生都不能睡午觉,所以通过我 ...
- 命令行连接wifi
ubuntu没有图形界面,插入无线网卡后启动不能连接无线. 看这个帖子 http://askubuntu.com/questions/138472/how-do-i-connect-to-a-wpa- ...
- FB接口之 js调用支付窗口
官方文档: https://developers.facebook.com/docs/reference/dialogs/pay/ <html xmlns="http://www.w3 ...
- android 高德地图出现【定位失败key鉴权失败】
如题:android 高德地图出现[定位失败key鉴权失败] 原因:使用的是debug模式下的SHA1,发布的版本正确获取SHA1的方式见: 方法二使用 keytool(jdk自带工具),按照如下步骤 ...
- 18、ESC/POS指令集在android设备上使用实例(通过socket)
网上关于通过android来操作打印机的例子太少了,为了方便更多的开发同仁,将近日所学分享一下. 我这边是通过android设备通过无线来对打印机(佳博58mm热敏式-58130iC)操作,实现餐厅小 ...
- windows下配置nodejs+npm
windows下安装nodejs是比较方便的 (v0.6.0之后,支持windows native),进入官网http://nodejs.org/ 点击install即可安装.下载完成后一路next ...
- .NET Framework 4.5、4.5.1 和 4.5.2 中的新增功能
.NET Framework 4.5.4.5.1 和 4.5.2 中的新增功能 https://msdn.microsoft.com/zh-cn/library/ms171868.aspx
- c++ assert
#include<iostream> #include <assert.h> using namespace std; int main() { ; assert(a == ) ...
- Discuz! X3.1去除内置门户导航/portal.php尾巴的方法
方法: 打开文件 /source/admincp/admincp_domain.php 查找 [php] if(!empty($domain) && in_array($domain, ...
- C# 中的 == 和 equals()有什么区别?
如以下代码: 1 2 3 4 5 6 7 8 9 int age = 25; short newAge = 25; Console.WriteLine(age == newAge); //t ...