算法练习笔记(二)

同样是对于数组的练习

这次尝试了Medium的难度

上周做完的题目一直忘了发上来= =


题目地址:https://leetcode.com/problems/game-of-life/

题目:Game of Life

分类:Array

难度:Medium

题目描述:

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."

根据维基百科所言:生存游戏,是在1970年由英国数学家John Horton Conway所发明的自动式化的细胞游戏。

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

给你一块遍布着m * n个细胞的培养方板,每个细胞都有着一个初始的状态生(1)或死(0),每个细胞的周围都有着八个方向的邻居(水平,垂直与对角),在游戏中,它们遵循着下列四种规则:

  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?
分析:

从上面的题目说明不难看出,细胞存在的状态分为两类,生(1)或死(0)

其中存活细胞只有周围有两个或三个邻居存活才能继续存活(1),否则灭亡(0)

死亡细胞如果周围有三个存活邻居则生(1),否则灭亡(0)

四种状态(1->1 邻居 = 2 or 3; 1->0 邻居 > 3 or <2; 0->1 邻居 = 3; 0->0 邻居≠ 3)

于是一切都变得清晰,对于这个二维数组,我们仅需要判断其本身的状态(0 or 1),再进行状态的计数就可以了

然而由于最后要求的是将原数组进行覆盖,在不想浪费建一个新数组的情况下,难免已经改变了的细胞会对其周围还没有改变的细胞造成影响

于是我们想到用特殊的数字来在表示其下一轮状态的同时,也能判断其上一轮的状态(棒)

因此将四种状态中,改变了的两种状态(1->0 & 0->1)用数字-1和2来表示

最终代码如下:


class Solution {
public:
    void gameOfLife(vector<vector<int>>& board) {
        int m,n;
        n = board[0].size();
        m = board.size();
    	for(int x = 0; x < m; x++){
    		for(int y = 0; y < n; y++){
    			int count = 0, flag = 0;
    			if(board[x][y] == 0){
    			    for(int i1 = max(x - 1, 0); i1 < min(x + 2, m); i1++ ){
    			        for(int i2 = max(y - 1, 0); i2 < min(y + 2, n); i2++){
    			            if(i1 == x && i2 == y)continue;
    			            if(board[i1][i2] == 1 || board[i1][i2] == -1)
    			            count ++;
    			        }
        			}
        			if(count == 3)board[x][y] = 2;
    			}
    			else if(board[x][y] == 1){
    			    for(int i1 = max(x - 1, 0); i1 < min(x + 2, m); i1++ ){
    			        for(int i2 = max(y - 1, 0); i2 < min(y + 2, n); i2++){
    			            if(i1 == x && i2 == y)continue;
    			            if(board[i1][i2] == 1 || board[i1][i2] == -1)
    			            count ++;
    			            if(count > 3){
    			                board[x][y] = -1;
    			                flag = 1;
    			            }
    			        }
    			        if(flag == 1)break;
        			}
        			if(count < 2)board[x][y] = -1;
    			}
    			
    		}
    	}
    	for(int x = 0; x < m; x++){
    		for(int y = 0; y < n; y++){
    			if(board[x][y] == 2)board[x][y] = 1;
    			if(board[x][y] == -1)board[x][y] = 0;
    		}
    	}
    			
    }
};

当然看到网上还有将每一位左移一位最后全部右移的做法,比起上面的代码确实会加快速度

但是打代码什么的,开心就好啦:-D



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值