Watch 10 video solutions for Game of Life, a medium level problem involving Array, Matrix, Simulation. This walkthrough by The Coding Train has 701,308 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
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.lengthn == board[i].length1 <= m, n <= 25board[i][j] is 0 or 1.
Follow up:
Problem Overview: You are given an m x n grid representing Conway’s Game of Life where each cell is either alive (1) or dead (0). Every cell updates simultaneously based on the number of live neighbors among the eight surrounding cells. The challenge is computing the next state of the board without corrupting neighbor calculations while you iterate through the grid.
Approach 1: Naive Approach with Extra Space (O(m*n) time, O(m*n) space)
Iterate through the grid and count the eight neighbors for each cell. Instead of updating the board immediately, store the next state in a separate m x n matrix. For each cell: if it is alive and has fewer than 2 or more than 3 live neighbors, it dies; if it has exactly 2 or 3 neighbors, it survives; a dead cell with exactly 3 neighbors becomes alive. After processing every cell, copy the new matrix back into the original board. This approach is straightforward and mirrors the rules directly, making it useful when clarity matters more than memory efficiency.
The main downside is the extra memory allocation. The algorithm still touches each cell once and checks up to eight neighbors, so the time complexity remains O(m*n). Space complexity is also O(m*n) due to the additional board. Problems like this commonly appear in array and matrix traversal scenarios where state must not be overwritten during iteration.
Approach 2: In-Place State Transition (O(m*n) time, O(1) space)
The optimal solution modifies the board in-place by encoding both the old and new states inside the same cell. While scanning the grid, mark transitional states instead of immediately overwriting values. A common encoding strategy uses:
-1 for a cell that was alive but becomes dead, and 2 for a cell that was dead but becomes alive. When counting neighbors, treat values 1 and -1 as originally alive because they represent cells that were alive before the update.
First pass: iterate through the grid, count neighbors, and assign transitional markers according to the Game of Life rules. Second pass: normalize the board by converting all positive values to 1 and all others to 0. Because transitional values preserve the previous state, neighbor counts remain correct even after partial updates.
This technique is a classic simulation pattern where temporary state encoding avoids extra memory. The board is still processed once, giving O(m*n) time complexity, while space complexity drops to O(1).
Recommended for interviews: Interviewers typically expect the in-place transition approach. The extra-space version demonstrates you understand the Game of Life rules and grid traversal, but the in-place encoding shows stronger problem-solving skills and awareness of memory optimization patterns commonly used in matrix simulations.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Naive Approach with Extra Space | O(m*n) | O(m*n) | Best for clarity and quick implementation when memory usage is not constrained |
| In-Place State Transition | O(m*n) | O(1) | Preferred in interviews and production when memory efficiency matters |