1. 程式人生 > >LeetCode 289.生命遊戲問題

LeetCode 289.生命遊戲問題

LeetCode-289.生命遊戲

生命遊戲問題

根據百度百科,生命遊戲,簡稱為生命,是英國數學家約翰·何頓·康威在1970年發明的細胞自動機。

給定一個包含 m × n 個格子的面板,每一個格子都可以看成是一個細胞。每個細胞具有一個初始狀態 live(1)即為活細胞, 或 dead(0)即為死細胞。每個細胞與其八個相鄰位置(水平,垂直,對角線)的細胞都遵循以下四條生存定律:

如果活細胞周圍八個位置的活細胞數少於兩個,則該位置活細胞死亡;
如果活細胞周圍八個位置有兩個或三個活細胞,則該位置活細胞仍然存活;
如果活細胞周圍八個位置有超過三個活細胞,則該位置活細胞死亡;
如果死細胞周圍正好有三個活細胞,則該位置死細胞復活;
根據當前狀態,寫一個函式來計算面板上細胞的下一個(一次更新後的)狀態。下一個狀態是通過將上述規則同時應用於當前狀態下的每個細胞所形成的,其中細胞的出生和死亡是同時發生的。

示例:

輸入:
[
[0,1,0],
[0,0,1],
[1,1,1],
[0,0,0]
]
輸出:
[
[0,0,0],
[1,0,1],
[0,1,1],
[0,1,0]
]
進階:

你可以使用原地演算法解決本題嗎?請注意,面板上所有格子需要同時被更新:你不能先更新某些格子,然後使用它們的更新後的值再更新其他格子。
本題中,我們使用二維陣列來表示面板。原則上,面板是無限的,但當活細胞侵佔了面板邊界時會造成問題。你將如何解決這些問題?

分析

本題需要對二維陣列有很好的理解
首先需要注意的是所有的細胞狀態需要同時改變,故我們應該建立一個二維陣列來儲存給定的board陣列每個一細胞將要改變的狀態。每個細胞周邊活細胞的獲取需建立一個方法來實現,我採用的方法是對每個座標四周八個點進行遍歷(需要注意陣列越界問題)具體見程式碼:
java程式碼片

.

class Solution {
    public void gameOfLife(int[][] board) {
        int maxRow=board.length;//行數4  y
        int maxColumn=board[0].length;//列數3  x
        int[][] arrs=new int[maxRow][maxColumn];
        for (int i=0;i<maxRow;i++){
            for (int j=0;j<maxColumn;j++){
                int count=FindLiveCellCount(i,j,maxRow,maxColumn,board);
                //System.out.println(count);
                //如果活細胞周圍八個位置的活細胞數少於兩個,則該位置活細胞死亡;
                if(count<2){
                    arrs[i][j]=0;
                }else if(count>3){
                    //如果活細胞周圍八個位置有兩個或三個活細胞,則該位置活細胞仍然存活;
                    //如果活細胞周圍八個位置有超過三個活細胞,則該位置活細胞死亡;
                    arrs[i][j]=0;
                }else if(count==3&&arrs[i][j]==0){
                    //如果死細胞周圍正好有三個活細胞,則該位置死細胞復活;
                    arrs[i][j]=1;
                }else{
                    arrs[i][j]=board[i][j];
                }
                //System.out.print(arrs[i][j]);
            }
            //System.out.println();
        }
       // board=arrs;
        
        
        for (int i=0;i<maxRow;i++) {
            for (int j = 0; j < maxColumn; j++) {
                board[i][j]=arrs[i][j];
            }
        }
        


    }
    public int FindLiveCellCount(int y, int x, int maxRow, int maxColumn, int[][] board){//統計細胞四周活細胞數量
        int count=0;//記錄傳入位置周邊狀體為1的數量
        if(x>=0&&y>=0&&maxRow>y&&maxColumn>x){
            //(x-1)
            if(x-1>=0){
                //(x-1,y+1)
                if(y<maxRow-1){
                    if (board[y+1][x-1]==1){
                        count++;
                    }
                }
                //(x-1,y)
                if(board[y][x-1]==1){
                    count++;
                }
                //(x-1,y-1)
                if(y>0){
                    if(board[y-1][x-1]==1){
                        count++;
                    }
                }

            }

            //x
            //(x,y+1)
            if(y<maxRow-1){
                if(board[y+1][x]==1){
                    count++;
                }
            }
            //(x,y-1)
            if(y>0){
                if(board[y-1][x]==1){
                    count++;
                }
            }

            //x+1
            if(x<maxColumn-1){
                //(x+1,y+1)
                if(y<maxRow-1){
                    if(board[y+1][x+1]==1){
                        count++;
                    }
                }
                //(x+1,y)
                if(board[y][x+1]==1){
                    count++;
                }
                //(x+1,y-1)
                if(y>0){
                    if(board[y-1][x+1]==1){
                        count++;
                    }
                }
            }
        }

        return count;
    }
}

作者:LiuK°