Game of Life I & II

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?

分析:https://segmentfault.com/a/1190000003819277

编解码法

复杂度

时间 O(NN) 空间 O(1)

思路

最简单的方法是再建一个矩阵保存,不过当inplace解时,如果我们直接根据每个点周围的存活数量来修改当前值,由于矩阵是顺序遍历的,这样会影响到下一个点的计算。如何在修改值的同时又保证下一个点的计算不会被影响呢?实际上我们只要将值稍作编码就行了,因为题目给出的是一个int矩阵,大有空间可以利用。这里我们假设对于某个点,值的含义为

0 : 上一轮是0,这一轮过后还是0
1 : 上一轮是1,这一轮过后还是1
2 : 上一轮是1,这一轮过后变为0
3 : 上一轮是0,这一轮过后变为1

这样,对于一个节点来说,如果它周边的点是1或者2,就说明那个点上一轮是活的。最后,在遍历一遍数组,把我们编码再解回去,即0和2都变回0,1和3都变回1,就行了。

注意

  • 注意编码方式,1和3都是这一轮过后为1,这样就可以用一个模2操作来直接解码了
  • 我实现的时候并没有预先建立一个对应周围8个点的数组,因为实际复杂度是一样,多加几个数组反而程序可读性下降
 1 public class Solution {
 2     public void gameOfLife(int[][] board) {
 3         int m = board.length, n = board[0].length;
 4         for(int i = 0; i < m; i++){
 5             for(int j = 0; j < n; j++){
 6                 int lives = 0;
 7                 // 判断上边
 8                 if(i > 0){
 9                     lives += board[i - 1][j] == 1 || board[i - 1][j] == 2 ? 1 : 0;
10                 }
11                 // 判断左边
12                 if(j > 0){
13                     lives += board[i][j - 1] == 1 || board[i][j - 1] == 2 ? 1 : 0;
14                 }
15                 // 判断下边
16                 if(i < m - 1){
17                     lives += board[i + 1][j] == 1 || board[i + 1][j] == 2 ? 1 : 0;
18                 }
19                 // 判断右边
20                 if(j < n - 1){
21                     lives += board[i][j + 1] == 1 || board[i][j + 1] == 2 ? 1 : 0;
22                 }
23                 // 判断左上角
24                 if(i > 0 && j > 0){
25                     lives += board[i - 1][j - 1] == 1 || board[i - 1][j - 1] == 2 ? 1 : 0;
26                 }
27                 //判断右下角
28                 if(i < m - 1 && j < n - 1){
29                     lives += board[i + 1][j + 1] == 1 || board[i + 1][j + 1] == 2 ? 1 : 0;
30                 }
31                 // 判断右上角
32                 if(i > 0 && j < n - 1){
33                     lives += board[i - 1][j + 1] == 1 || board[i - 1][j + 1] == 2 ? 1 : 0;
34                 }
35                 // 判断左下角
36                 if(i < m - 1 && j > 0){
37                     lives += board[i + 1][j - 1] == 1 || board[i + 1][j - 1] == 2 ? 1 : 0;
38                 }
39                 // 根据周边存活数量更新当前点,结果是0和1的情况不用更新
40                 if(board[i][j] == 0 && lives == 3){
41                     board[i][j] = 3;
42                 } else if(board[i][j] == 1){
43                     if(lives < 2 || lives > 3) board[i][j] = 2;
44                 }
45             }
46         }
47         // 解码
48         for(int i = 0; i < m; i++){
49             for(int j = 0; j < n; j++){
50                 board[i][j] = board[i][j] % 2;
51             }
52         }
53     }
54 }

Game of Life II

In Conway‘s Game of Life, cells in a grid are used to simulate biological cells. Each cell is considered to be either alive or dead. At each step of the simulation each cell‘s current status and number of living neighbors is used to determine the status of the cell during the following step of the simulation.

In this one-dimensional version, there are N cells numbered 0 through N-1. The number of cells does not change at any point in the simulation. Each cell i is adjacent to cells i-1 and i+1. Here, the indices are taken modulo N meaning cells 0 and N-1 are also adjacent to eachother. At each step of the simulation, cells with exactly one living neighbor change their status (alive cells become dead, dead cells become alive).

For example, if we represent dead cells with a ‘0‘ and living cells with a ‘1‘, consider the state with 8 cells: 01100101 Cells 0 and 6 have two living neighbors. Cells 1, 2, 3, and 4 have one living neighbor. Cells 5 and 7 have no living neighbors. Thus, at the next step of the simulation, the state would be: 00011101

 1 public void solveOneD(int[] board){
 2     int n = board.length;
 3     int[] buffer = new int[n];
 4     // 根据每个点左右邻居更新该节点情况。
 5     for(int i = 0; i < n; i++){
 6         int lives = board[(i + n + 1) % n] + board[(i + n - 1) % n];
 7         if(lives == 1){
 8             buffer[i] = (board[i] + 1) % 2;
 9         } else {
10             buffer[i] = board[i];
11         }
12     }
13     for(int i = 0; i < n; i++){
14         board[i] = buffer[i];
15     }
16 }
 1 public void solveOneD(int rounds, int[] board){
 2     int n = board.length;
 3     for(int i = 0; i < n; i++){
 4         int lives = board[(i + n + 1) % n] % 2 + board[(i + n - 1) % n] % 2;
 5         if(lives == 1){
 6             board[i] = board[i] % 2 + 2;
 7         } else {
 8             board[i] = board[i];
 9         }
10     }
11     for(int i = 0; i < n; i++){
12         board[i] = board[i] >= 2 ? (board[i] + 1) % 2 : board[i] % 2;
13     }
14 }
时间: 2024-09-28 21:41:13

Game of Life I & II的相关文章

[LeetCode] 349 Intersection of Two Arrays &amp; 350 Intersection of Two Arrays II

这两道题都是求两个数组之间的重复元素,因此把它们放在一起. 原题地址: 349 Intersection of Two Arrays :https://leetcode.com/problems/intersection-of-two-arrays/description/ 350 Intersection of Two Arrays II:https://leetcode.com/problems/intersection-of-two-arrays-ii/description/ 题目&解法

使用华邦的SPI FLASH作为EPCS时固化NIOS II软件报错及解决方案

Altera器件有EPCS系列配置器件,其实,这些配置器件就是我们平时通用的SPIFlash,据AlteraFAE描述:"EPCS器件也是选用某家公司的SPIFlash,只是中间经过Altera公司的严格测试,所以稳定性及耐用性都超过通用的SPIFlash".就本人看来,半导体的稳定性问题绝大部分都是由本身设计缺陷造成的,而成熟的制造工艺不会造成产品的不稳定:并且,现在Altera的器件在读入配置数据发生错误时,可以重新读取SPIFlash里面的数据,所以在工艺的稳定性以及设计的可靠性

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

AC日记——小A和uim之大逃离 II 洛谷七月月赛

小A和uim之大逃离 II 思路: spfa: 代码: #include <bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f struct NodeType { int x,y,k; NodeType(int x_,int y_,int k_):x(x_),y(y_),k(k_){} NodeType(){} }; const int dx[5]={0,-1,0,1,0}; const int dy[5]={0,0,1,0,-

remove-duplicates-from-sorted-list I&amp;II——去除链表中重复项

I.Given a sorted linked list, delete all duplicates such that each element appear only once. For example,Given1->1->2, return1->2.Given1->1->2->3->3, return1->2->3. PS:遍历,而后记录pre,并删除后续重复node 1 /** 2 * Definition for singly-linke

Intersection of Two Arrays I &amp; II

题目链接:https://leetcode.com/problems/intersection-of-two-arrays/ 题目大意:要求两个数组的交集(注意集合是不能含有重复的元素的) 方法1) 先对两个数组进行排序,设置两个指针pA和pB,分别指向这两个数组,比较nums1[pA]和nums[pB] a. 如果想等,则为交集中的元素,++pA, ++pB b. 如果nums[pA] < nums[pB],则++pA c. 否则,++pB 注意数组中有重复的元素(实现代码中的小trick)

Wiggle Sort II

Wiggle Sort II Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3].... 注意事项 You may assume all input has valid answer. 样例 Given nums = [1, 5, 1, 1, 6, 4], one possible answer is [1, 4, 1, 5, 1, 6]. Given nums

1245 - Harmonic Number (II)(规律题)

1245 - Harmonic Number (II)   PDF (English) Statistics Forum Time Limit: 3 second(s) Memory Limit: 32 MB I was trying to solve problem '1234 - Harmonic Number', I wrote the following code long long H( int n ) {     long long res = 0;     for( int i =

LeetCode:Spiral Matrix II - 将元素1-n^2以螺旋序填充到矩阵

1.题目名称 Spiral Matrix(螺旋输出矩阵中的元素) 2.题目地址 https://leetcode.com/problems/spiral-matrix-ii/ 3.题目内容 英文:Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. 中文:给出一个整数n,生成一个矩阵,使用数字1到n^2以螺旋顺序填充这个矩阵 例如:给出n=3,则生成如下矩阵:

[LeetCode]Binary Tree Level Order Traversal II

Binary Tree Level Order Traversal II Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). For example:Given binary tree {3,9,20,#,#,15,7}, 3 / 9 20 / 15 7 re