289. Game of Life(Leetcode每日一题-2020.04.02)

Problem

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.

Example1

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]
]

Solution

Solution1

因为要同步更新,所以想到将输入的board复制一份为copy_board,然后参照copy_board对board进行更新。

class Solution {
public:
    void gameOfLife(vector<vector<int>>& board) {
        if(board.empty())
            return;
        int rows = board.size();
        int cols = board[0].size();

        vector<vector<int>> copy_board(rows,vector<int>(cols,0));

        for(int i = 0;i<rows;++i)
            for(int j = 0;j<cols;++j)
            {
                copy_board[i][j] = board[i][j];
            }


        vector<int> dir = {-1,0,1};
        for(int i = 0;i<rows;++i)
            for(int j = 0;j<cols;++j)
            {
                int live_neighbor = 0;
                //注意如何遍历相邻的八个位置
                for(int r = 0;r<dir.size();++r)
                    for(int c = 0;c < dir.size();++c)
                    {
                        if(!(dir[r] == 0 && dir[c] == 0))
                        {
                            int n_r = i + dir[r];
                            int n_c = j + dir[c];
                            
                            if(n_r >= 0 && n_r < rows && n_c >=0 && n_c < cols)
                            {
                                if(copy_board[n_r][n_c] == 1)
                                    ++live_neighbor;
                            }
                        }
                    }

                if(copy_board[i][j] == 1)
                {
                    if(live_neighbor < 2)
                        board[i][j] = 0;
                    else if(live_neighbor == 2 || live_neighbor == 3)
                        board[i][j] = 1;
                    else
                        board[i][j] = 0;
                }
                else
                {
                    if(live_neighbor == 3)
                        board[i][j] = 1;
                }
            }



    }
};

Solution2

原地法。
每个细胞的状态只会是0或1,它只会占用int的最低位。在更新过程中,我们可以使用int的次低位存储board上每个位置在下一轮的状态。

class Solution {
public:
    void gameOfLife(vector<vector<int>>& board) {
        if(board.empty())
            return;
        int rows = board.size();
        int cols = board[0].size();

        vector<int> dir = {-1,0,1};

        for(int i = 0;i<rows;++i)
            for(int j = 0;j<cols;++j)
            {
                int live_neighbor = 0;
                for(int r = 0;r<dir.size();++r)
                    for(int c = 0;c < dir.size();++c)
                    {
                        if(!(dir[r] == 0 && dir[c] == 0))
                        {
                            int n_r = i + dir[r];
                            int n_c = j + dir[c];
                            if(n_r >= 0 && n_r < rows && n_c >=0 && n_c < cols)
                            {
                                if(board[n_r][n_c] & 1 == 1)
                                    ++live_neighbor;
                            }
                        }
                    }

                if(board[i][j] & 1 == 1)
                {
                    if(live_neighbor < 2)
                        board[i][j] |= 0;
                    else if(live_neighbor == 2 || live_neighbor == 3)
                        board[i][j] |= 2;
                    else
                        board[i][j] |= 0;
                }
                else
                {
                    if(live_neighbor == 3)
                        board[i][j] |= 2;
                }
            }

        

        
        for(int i = 0;i<rows;++i)
            for(int j = 0;j<cols;++j)
            {
                board[i][j] = board[i][j] >> 1;
            }



    }
};
发布了547 篇原创文章 · 获赞 217 · 访问量 56万+

猜你喜欢

转载自blog.csdn.net/sjt091110317/article/details/105278877