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):

  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?

Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.

看到这么长的题目,我决定翻译一下:

根据维基百科的文章:“生命的游戏,也被称为生命,是1970年由英国数学家约翰·霍顿·康威(John Horton Conway)设计的一种细胞自动机。”

给定一个有m*n个细胞的单元格,每个细胞有一个初始的状态活着(1)或者死亡(0)。每个细胞与其他8个细胞(水平,垂直,对角线)使用下面四条规则进行交互(取自上述的维基百科文章):

1.任意活着的细胞,它周围的细胞活着的少于两个,那么它会死亡,由于人口太少造成的;

2.任意活着的细胞,它周围活着的细胞是2-3个的话,它会活到下一代;

3.任意细胞的周围有超过三个活着的细胞,就会死亡,因为人口太多;

4.任意死亡的细胞,当它的周围有三个活着的细胞,它就会变成活着的细胞,因为繁殖。

当给定当前状态的单元格之后,写一个函数计算出它的下一状态。

所以总结上述四条规则,可以画出下面的图:


如果一个细胞现在是活着的,当它周围的存活细胞数是2个或者3个的时候,它能在下一个状态继续或者,否则就会死亡,如果一个细胞现在是死亡状态,当它周围的存活细胞数是3个的时候,它又能活过来,反之则是继续死亡。

可以用二进制的数来表示状态改变的过程,因为每个细胞的下一个状态默认是死亡的,所以只需要考虑两种状态转移情况:

00——>01

01——>11

(这里面的数字:第一个表示当前状态,第二个表示下一个状态,比如01表示由活着到死亡,11表示由活着到活着)

为了从转移后的状态取出下一个状态,只需要将当前状态的数字右移一位即可

代码如下,有详细解释:

if(board==null||board.length==0){return;}
		int m = board.length;
		int n = board[0].length;
		//状态转移过程
		for(int i=0;i<m;i++){
			for(int j=0;j<n;j++){
				int lives = lives(board,m,n,i,j);
				//如果现在的状态是死亡并且周围有三个细胞存活,那么它的状态变为活着
				if(board[i][j]==0&&lives==3){
					//由00-->10
					board[i][j] = 2;
				}
				//如果现在的状态是活着并且周围有2个或3个或者的细胞,它将会继续存活
				if(board[i][j]==1&&(lives==2||lives==3)){
					//01-->11
					board[i][j] = 3;
				}
			}
		}
		//右移一位取出下一步的状态
		for(int i=0;i<m;i++){
			for(int j=0;j<n;j++){
				board[i][j] = board[i][j]>>1;
			}
		}
		
		
	}
	//这个函数用于计算一个细胞周围的存活细胞数
	public int lives(int [][] board, int m, int n,int i,int j){
		int lives=0;
		
	//因为要搜索的范围是它的上一行到下一行,与它相邻左边一列到右边一列,(i-1~i+1),(j-1~j+1),
	//但是出于边界的考虑,需要将x,y与0和m-1,n-1比较
		for(int x = Math.max(0, i-1);x<=Math.min(m-1, i+1);x++){
			for(int y = Math.max(0, j-1);y<=Math.min(n-1, j+1);y++){
				lives += board[x][y]&1;
			}
		}
		//最后减去当前位置的细胞存活或者死亡的数字,因为计算它周围的存活细胞数时将它本身也计算在内了,所以现在要减掉
		lives -= board[i][j]&1;
		return lives;



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值