LeetCode:Game of Life

3537 ワード

Game of Life
Total Accepted: 20082 
Total Submissions: 57678 
Difficulty: Medium
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:  1.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.
2.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?
Credits: Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.
Subscribe to see which companies asked this question
Hide Tags
 
Array
Hide Similar Problems
 
(M) Set Matrix Zeroes
考え方:
細胞の転化状況は4種類あります.
dead -> dead
live-> dead
dead-> live
live-> live
タイトル要求でin-placeでその場で操作します.従って、変換の過程において、変換結果を体現しても、変換前の状態を保持しなければならない.
変換前後とも2つの状態であるため、2つのbitで表すことができる:[bit 2,bit 1]
bit 1:変換前状態;
bit 2:変換後の状態.
したがって、上記の変換は、
00:dead <- dead
01:dead <- live
10:live <- dead
11:live <- live
bit 2のデフォルトは0なので、10と11の2つのケースだけを考慮すればいいです.
board[i][j]&1:bit 1をとる;
board[i][j]>>1:bit 2をとる.
java code:
public class Solution {
    public void gameOfLife(int[][] board) {
        
        if(board == null || board.length == 0) return;
        
        int rows = board.length;
        int cols = board[0].length;
        
        for(int i=0;i<rows;i++) {
            for(int j=0;j<cols;j++) {
                int lives = liveInNeighbors(board, rows, cols, i, j);
                
                //     2 0->1 1->1     ,   2    0
                if(board[i][j]==0 && lives==3)
                    board[i][j] = 2;
                if(board[i][j]==1 && (lives==2 || lives==3))
                    board[i][j] = 3;
            }
        }
        
        for(int i=0;i<rows;i++) {
            for(int j=0;j<cols;j++) {
                board[i][j] >>= 1; //    
            }
        }
    }
    
    private int liveInNeighbors(int board[][], int rows, int cols, int row, int col) {
        
        int lives = 0;
        
        for(int i = Math.max(0, row-1);i <= Math.min(rows-1, row+1);i++) {
            for(int j = Math.max(0, col-1);j <= Math.min(cols-1, col+1);j++) {
                lives += board[i][j] & 1; //    
            }
        }
        lives -= board[row][col] & 1;
        return lives;
    }
}