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

    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.

    Follow up:
    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.
    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. 一個活的格子若只有一個或沒有鄰居, 在下一秒將因寂寞而亡;
    2. 一個活的格子若有四個或四個以上的鄰居, 在下一秒將因拥擠而亡;
    3. 一個活的格子若有二個或三個鄰居, 在下一秒將継續活著;
    4. 一個死的格子若有三個鄰居, 在下一秒將活過來;

    题目要求inplace实现,不允许额外申请空间。

    若是不考虑占用空间,我们很容易可以解决该问题。首先,保存原始棋盘用于计算邻居live状态的数目。然后依据条件修改board每个cell的状态即可。

    若是不允许申请空间,我们必须在不改变原始棋盘状态的情况下,记录出每个cell应该怎么变化;
    使用不同数值(十进制)代表状态 0 :dead; 10 :dead—>live; 11:live—>live; 1:live;
    具体实现见代码!

    AC代码

    class Solution {
    public:
        //方法一:复制原来棋盘,空间复杂度为O(n)
        void gameOfLife1(vector<vector<int>>& board) {
            if (board.empty())
                return;
    
            //求出所给定棋盘的行列
            int m = board.size(), n = board[0].size();
    
            vector<vector<int>> tmp(board.begin(), board.end());
            for (int i = 0; i < m; ++i)
            {
                for (int j = 0; j < n; ++j)
                {
                    int count = getLiveNum(tmp, i, j);
                    if (board[i][j] == 0)
                    {
                        //dead状态
                        if (count == 3)
                            board[i][j] = 1; //dead —> live
                    }//if
                    else{
                        //live状态
                        if (count > 3)
                        {
                            board[i][j] = 0; //live—>dead
                        }//if
                        //若是count == 2 || count == 3 则live—>dead,board[i][j]值不变
                    }//else
                }//for
            }//for
            return;
        }
    
        //方法二:inplace 使用不同数值(十进制)代表状态 0 :dead;  10 :dead—>live; 11:live—>live;  1:live;
        void gameOfLife(vector<vector<int>>& board) {
            if (board.empty())
                return;
    
            //求出所给定棋盘的行列
            int m = board.size(), n = board[0].size();
            for (int i = 0; i < m; ++i)
            {
                for (int j = 0; j < n; ++j)
                {
                    int count = getLiveNum(board, i, j);
                    if (board[i][j] == 0)
                    {
                        //dead状态
                        if (count == 3)
                            board[i][j] += 10; //dead —> live
                    }
                    else{
                        //live状态
                        if (count == 2 || count == 3)
                        {
                            board[i][j] += 10; //live—>live
                        }//if
                        //若是count>=4 则live—>dead,board[i][j]值不变
                    }//else
                }//for
            }//for
            //更新状态
            for (int i = 0; i < m; ++i)
            {
                for (int j = 0; j < n; ++j)
                {
                    board[i][j] /= 10;
                }//for
            }//for
            return;
        }
    
        //计算位于(r,c)邻居,live状态的数量
        int getLiveNum(vector<vector<int>> &board, int x, int y)
        {
            int count = 0;
            for (int i = x - 1; i <= x + 1; ++i)
            {
                for (int j = y - 1; j <= y + 1; ++j)
                {
                    if (i < 0 || j < 0 || i >= board.size() || j >= board[x].size() || (x == i && j == y))  
                    {
                        continue;
                    }
                    else{
                        if (board[i][j] % 10 == 1)
                            ++count;
                    }//else
                }//for
            }//for
            return count;
        }
    
    };
    

    GitHub测试程序源码

  • 相关阅读:
    图像识别模型
    W tensorflow/core/util/ctc/ctc_loss_calculator.cc:144] No valid path found 或 loss:inf的解决方案
    CF1240F Football
    loj6537. 毒瘤题加强版再加强版
    Codeforces Global Round 9题解
    CF356E Xenia and String Problem
    CF1185G2 Playlist for Polycarp
    CF914F Substrings in a String
    Python3.5学习之旅一
    python内置数据结构性能分析
  • 原文地址:https://www.cnblogs.com/shine-yr/p/5214742.html
Copyright © 2011-2022 走看看