zoukankan      html  css  js  c++  java
  • LeetCode-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. The next state is created by applying the above rules simultaneously to every cell in the current state, where births and deaths occur simultaneously.

    题目大意

    给定一个二维数组,数组中只包含0和1(其中0代表死亡,1代表存活),要求根据以下的状态计算方法,计算出该矩阵的下一个状态:

    1. 若当前位置为1,且其邻居中1的个数少于2个,则将其置0;(其中的邻居为该位置的相邻的八个方向的位置)

    2. 若当前位置为1,且其邻居中的1的个数为2个或3个,则保持1不变;

    3. 若当前位置为1,且其邻居中的1的个数大于3,则将其置0;

    4. 若当前位置为0,且其邻居中的1的个数等于3,则将其置1,否则不变。

    (PS:要求在当前的数组中进行操作,尽量不要用多余的数组空间)

    示例

    E1

    Input: 
    [
      [0,1,0],
      [0,0,1],
      [1,1,1],
      [0,0,0]
    ]
    Output: 
    [
      [0,0,0],
      [1,0,1],
      [0,1,1],
      [0,1,0]
    ]

    解题思路

    简单遍历一边数组,同时判断其邻居的状态,根据要求进行改变,为了不影响之后的位置对其邻居的判断,可以将其其改变为2和3(2:从0变成1,3:从1变成0),因此若邻居中出现2则代表其等于0,若出现3则代表为1 。

    第二遍遍历一遍数组,将2和3分别改为1和0 。即完成在当前数组进行状态的变化。

    复杂度分析

    时间复杂度:O(N)

    空间复杂度:O(1)

    代码

    class Solution {
    public:
        void gameOfLife(vector<vector<int>>& board) {
            int m, n;
            m = board.size();
            if(m)
                n = board[0].size();
            else
                return;
            // 第一遍遍历数组
            for(int i = 0; i < m; ++i) {
                for(int j = 0; j < n; ++j) {
                    int live = 0;
                    // 查找邻居中的1的数量
                    for(int k = 0; k < 8; ++k) {
                        int tx = i + nei[k][0], ty = j + nei[k][1];
                        if(tx >= 0 && tx < m && ty >= 0 && ty < n) {
                            // 注意若其中存在3,则也代表为1
                            live += board[tx][ty] % 2;
                        }
                    }
                    // 根据规则进行变化,若其为0->1的变化则置2,若为1->0的变化则置3
                    if(board[i][j]) {
                        if(live < 2 || live > 3)
                            board[i][j] = 3;
                    }
                    else {
                        if(live == 3)
                            board[i][j] = 2;
                    }
                }
            }
            // 第二遍遍历数组,将其中的2和3分别置1和0
            for(int i = 0; i < m; ++i) {
                for(int j = 0; j < n; ++j) {
                    if(board[i][j] == 2)
                        board[i][j] = 1;
                    if(board[i][j] == 3)
                        board[i][j] = 0;
                }
            }
        }
        
    private:
        // 保存8个邻居的位置,方便进行邻居状态的判断
        int nei[8][2] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
    };
  • 相关阅读:
    如何用js解网页中间内容的高度自适应
    常见Js获取高宽度的方法
    CSS3 转换 transform
    CSS3 过渡 transition
    CSS3 动画 animation
    当页面内容不够的时候,如何让footer一直固定底部显示
    如何用js判断是否为手机访问
    用css解决table文字溢出控制td显示字数
    jquery实现全选和反选功能
    JS中filter的用法
  • 原文地址:https://www.cnblogs.com/heyn1/p/11149801.html
Copyright © 2011-2022 走看看