Leetcode 289. Game of Life

题目描述

  1. Game of Life
    Medium

647

131

Favorite

Share
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. The next state is created by applying the above rules simultaneously to every cell in the current state, where births and deaths occur simultaneously.

解题思路

本题解题比较简单,就是遍历每一个cell,然后计算出neightbor的live数量,然后改变状态,之所以有难度就是因为后面的cell需要依赖前面的cell(cell[i,j] 需要依赖cell[i-1,j-1],但是cell[i-1,j-1]的状态已经变化了),但是前面的cell状态已经改变了,所以我们需要保存最初的状态。参考他人discuss,采取一个小技巧就是使用二进制.比如:十进制 1 的二进制01, 表示由1 变为0;十进制3 的二进制11 表示由1变为1.
转换规则如下:

  1. 邻居live数量小于2, 1 -> 0;
  2. 邻居live数量等于2或者等于3, 1->1;
  3. 邻居live数量大于等于4, 1->0;
  4. 邻居live数量等于3, 0->1.
    根据上面的情况其实case 1,3我们不需要处理,1 和 01的数值是一样的。下面给出代码。

代码

//向量用于遍历邻居
int []dimx = new int[]{-1,1,0,0,-1,-1,1,1};
    int []dimy = new int[]{0,0,-1,1,-1,1,-1,1};

    public void gameOfLife(int[][] board) {
        int n = board.length;
        int m = board[0].length;
        if (n==0||m==0) return;
        for (int i = 0;i<n;i++) {
            for(int j=0;j<m;j++) {
                int live = liveNeighbor(board,i,j,n,m);
                if(board[i][j] == 1 && (live==2 || live ==3)) {
                    board[i][j] = 3;
                } else if(board[i][j] == 0 && live == 3) {
                    board[i][j] = 2;
                }
            }
        }
//恢复数据
        for (int i=0;i<n;i++){
            for(int j=0;j<m;j++) {
                board[i][j] >>= 1;
            }
        }
    }
//计算live邻居的数量
    int liveNeighbor(int[][] board,int i,int j,int n,int m) {
        int live = 0;
        for (int k=0;k<8;k++){
            int tmpi = i + dimx[k];
            int tmpj = j + dimy[k];
            if(tmpi>=0 && tmpi<n && tmpj >=0 && tmpj<m) {
                live += board[tmpi][tmpj] & 1;
            }
        }
        return live;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值