Sale: Get 60% Off on all Pro Plans. Buy Now

Game of Life

Medium Matrix Traversal

Problem

Given a 2D board representing the current state of cells (1 for live, 0 for dead), update the board to the next state according to the Game of Life rules simultaneously for all cells.

  • m == board.length
  • n == board[i].length
  • 1 ≤ m, n ≤ 25
  • board[i][j] is 0 or 1

Example

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

Starting with the given board, the algorithm counts live neighbors for each cell. For example, the cell at (1,0) is dead but has exactly three live neighbors, so it becomes live (value 1). The cell at (0,1) is live but has only one live neighbor, so it dies (value 0). The algorithm uses temporary markers (-1 for live-to-dead, 2 for dead-to-live) to track transitions without affecting neighbor counts. After processing all cells, it finalizes the board by converting temporary markers to their final states.

Approach

Straightforward Solution

A naive approach would create a copy of the board to compute the next state, then copy it back. This uses O(m*n) extra space, which is inefficient for large boards.

Core Observation

The next state of each cell depends on the count of live neighbors, but all updates must happen simultaneously. This means the algorithm cannot update the board in-place naively, as changes would affect neighbor counts of other cells.

Path to Optimal

Preview

The key insight is to encode state transitions in-place using temporary markers that distinguish between original and next states…

Full step-by-step walkthrough on Pro

Optimal Approach

Preview

Traverse each cell, count live neighbors by checking all eight directions and considering cells with absolute value 1 as originally live. Apply the rules and mark transitions with temporary values (-1 for live-to-dead, 2 for dead-to-live)…

Full step-by-step walkthrough on Pro

Want the full reasoning chain?

Unlock the complete walkthrough, line-by-line analysis, and recall drill.

Unlock Pro

Time

O(m * n)

Each cell is visited twice: once to compute neighbor counts and mark transitions, and once to finalize states. Each neighbor check is constant time (8 directions), so total time is proportional to the number of cells.

Space

O(1)

The algorithm uses only a fixed set of temporary markers and a constant-size directions array, modifying the board in-place without additional data structures proportional to input size.

Pattern Spotlight

Matrix Traversal (In-Place State Encoding)

When simultaneous updates depend on neighbors' original states, encode transitions with temporary markers that preserve original information during traversal, enabling in-place updates without extra space.

Solution

Python
1class Solution:
2 def gameOfLife(self, board: List[List[int]]) -> None:
3 rows = len(board)
4 cols = len(board[0])
5
6 directions = [
7 (-1, -1), (-1, 0), (-1, 1),
8 (0, -1), (0, 1),
9 (1, -1), (1, 0), (1, 1)
10 ]
11
12 for r in range(rows):
13 for c in range(cols):
14 live_neighbors = 0
15
16 for dr, dc in directions:
17 nr = r + dr
18 nc = c + dc
19
20 if 0 <= nr < rows and 0 <= nc < cols and abs(board[nr][nc]) == 1:
21 live_neighbors += 1
22
23 if board[r][c] == 1 and (live_neighbors < 2 or live_neighbors > 3):
24 board[r][c] = -1
25
26 if board[r][c] == 0 and live_neighbors == 3:
27 board[r][c] = 2
28
29 for r in range(rows):
30 for c in range(cols):
31 if board[r][c] > 0:
32 board[r][c] = 1
33 else:
34 board[r][c] = 0

Step-by-Step Solution

1

Count Live Neighbors and Mark State Transitions In-Place

3rows = len(board)
4cols = len(board[0])
6directions = [
7 (-1, -1), (-1, 0), (-1, 1),
8 (0, -1), (0, 1),
9 (1, -1), (1, 0), (1, 1)
12for r in range(rows):
13 for c in range(cols):
14 live_neighbors = 0
16 for dr, dc in directions:
17 nr = r + dr
18 nc = c + dc
20 if 0 <= nr < rows and 0 <= nc < cols and abs(board[nr][nc]) == 1:
21 live_neighbors += 1
23 if board[r][c] == 1 and (live_neighbors < 2 or live_neighbors > 3):
24 board[r][c] = -1
26 if board[r][c] == 0 and live_neighbors == 3:
27 board[r][c] = 2

Objective

To iterate over each cell, count its live neighbors considering original states, and mark cells with temporary values to indicate state changes without losing original information.

Key Insight

Using the absolute value of cell states allows the algorithm to distinguish originally live cells (abs == 1) from dead ones, even after marking transitions. This enables accurate neighbor counts while performing in-place updates. Marking live-to-dead as -1 and dead-to-live as 2 encodes transitions without interfering with neighbor calculations.

Interview Quick-Check

Core Logic

Count live neighbors by checking all eight directions and using abs(board[nr][nc]) == 1 to identify originally live cells, ensuring neighbor counts remain accurate despite in-place updates.

State & Boundaries

Check boundary conditions for neighbors (0 <= nr < rows and 0 <= nc < cols) to avoid index errors.

Common Pitfalls & Bugs

Failing to use absolute values when counting neighbors leads to incorrect counts because temporary markers (-1, 2) would be misinterpreted.

Complexity

This step runs in O(m*n) time, with a constant factor of 8 for neighbor checks, which is efficient for the problem constraints.

2

Finalize Board by Converting Temporary Markers to Final States

To traverse the board again and convert all temporary markers to their final live or dead states, completing the simultaneous update.

1 more step with full analysis available on Pro.

Line Analysis

This solution has 3 Critical lines interviewers watch for.

Line 20 Critical
if 0 <= nr < rows and 0 <= nc < cols and abs(board[nr][nc]) == 1:

Check if neighbor is within board boundaries and originally live.

This condition is critical because it preserves the original state information during in-place updates, enabling accurate neighbor counts even when cells have been marked for state changes.

Line 23 Critical
if board[r][c] == 1 and (live_neighbors < 2 or live_neighbors > 3):

Mark live cells that die due to underpopulation or overpopulation.

Marking with -1 allows the algorithm to distinguish cells that were originally live but will die, preserving original state information for neighbor counts while encoding the next state.

Line 26 Critical
if board[r][c] == 0 and live_neighbors == 3:

Mark dead cells that become live due to reproduction.

Marking with 2 allows the algorithm to distinguish cells that were originally dead but will become live, enabling simultaneous updates without corrupting neighbor counts.

Full line-by-line criticality + rationale for all 24 lines available on Pro.

Test Your Understanding

Why does the algorithm use temporary markers like -1 and 2 instead of directly updating cells to 0 or 1 during the first pass?

See the answer with Pro.

Related Problems

Matrix Traversal pattern

Don't just read it. Drill it.

Reconstruct Game of Life from memory until it sticks. AlgoDrill blanks out key lines and makes you fill them back in, step by step.

Unlock the Game of Life drill

or drill a free problem