According to 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."
The board is made up of an m x n
grid of cells, where each cell has an initial state: live (represented by a 1
) or dead (represented by a 0
). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article):
The next state of the board is determined by applying the above rules simultaneously to every cell in the current state of the m x n
grid board
. In this process, births and deaths occur simultaneously.
Given the current state of the board
, update the board
to reflect its next state.
Note that you do not need to return anything.
Example 1:
Input: board = [[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]]
Example 2:
Input: board = [[1,1],[1,0]] Output: [[1,1],[1,1]]
Constraints:
m == board.length
n == board[i].length
1 <= m, n <= 25
board[i][j]
is 0
or 1
.
Follow up:
This problem simulates Conway's Game of Life, updating the state of a cellular automaton based on the number of live neighbors each cell has. The challenge lies in performing the updates simultaneously, without using extra space.
The most efficient solution uses in-place marking and avoids creating a copy of the board. We leverage the fact that each cell's value is either 0 or 1. We can cleverly use the least significant bit to represent the current state (0 or 1) and the most significant bit to represent the next state.
Algorithm:
Iteration 1: Count Live Neighbors and Update: Iterate through the board. For each cell:
Iteration 2: Update Final State: Iterate through the board again. For each cell, update its value based on the most significant bit:
Time and Space Complexity:
Code Example (Python):
def gameOfLife(board):
m, n = len(board), len(board[0])
for i in range(m):
for j in range(n):
live_neighbors = 0
for x in range(max(0, i - 1), min(m, i + 2)):
for y in range(max(0, j - 1), min(n, j + 2)):
if (x, y) != (i, j) and board[x][y] & 1: # Check current state (LSB)
live_neighbors += 1
if board[i][j] & 1: # Check current state (LSB)
if live_neighbors < 2 or live_neighbors > 3:
board[i][j] |= 2 # Mark for death (set MSB)
else:
if live_neighbors == 3:
board[i][j] |= 2 # Mark for birth (set MSB)
for i in range(m):
for j in range(n):
board[i][j] >>= 1 # Right-shift to reveal next state (LSB)
This Python code directly implements the bit manipulation approach for clarity. Other languages (Java, C++, etc.) would achieve the same using equivalent bitwise operators. Note that the core concept remains consistent across all languages: using the bit pattern to efficiently manage the current and next states within the existing board.