Top Interview 150
The Game of Life problem is a simulation-based challenge involving matrix updates and in-place operations. Letβs solve LeetCode 289: Game of Life while ensuring the board is updated simultaneously, as required.
π Problem Description
Given an mΓn grid representing a board, where:
- 1: A cell is live.
- 0: A cell is dead.
The rules to determine the next state of the board are:
- Any live cell with fewer than two live neighbors dies (underpopulation).
- Any live cell with two or three live neighbors lives.
- Any live cell with more than three live neighbors dies (overpopulation).
- Any dead cell with exactly three live neighbors becomes live (reproduction).
The challenge: Update the board in place to reflect its next state.
π‘ Examples
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]]
Input: board = [[1, 1], [1, 0]]
Output: [[1, 1], [1, 1]]
π JavaScript Solution
To update the board in place while maintaining the original state for simultaneous updates, we use state encoding:
- Intermediate States:
- 2: A cell was live but will become dead.
- 3: A cell was dead but will become live.
Implementation
var gameOfLife = function(board) {
const rows = board.length;
const cols = board[0].length;
const countLiveNeighbors = (row, col) => {
let liveCount = 0;
const directions = [
[-1, -1], [-1, 0], [-1, 1],
[0, -1], [0, 1],
[1, -1], [1, 0], [1, 1],
];
for (const [dr, dc] of directions) {
const r = row + dr, c = col + dc;
if (r >= 0 && r < rows && c >= 0 && c < cols && (board[r][c] === 1 || board[r][c] === 2)) {
liveCount++;
}
}
return liveCount;
};
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
const liveNeighbors = countLiveNeighbors(row, col);
if (board[row][col] === 1) {
if (liveNeighbors < 2 || liveNeighbors > 3) {
board[row][col] = 2; // Live -> Dead
}
} else {
if (liveNeighbors === 3) {
board[row][col] = 3; // Dead -> Live
}
}
}
}
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
if (board[row][col] === 2) {
board[row][col] = 0; // Live -> Dead
} else if (board[row][col] === 3) {
board[row][col] = 1; // Dead -> Live
}
}
}
};
π How It Works
-
Count Live Neighbors:
- Use an array of 8 directions to check all neighboring cells for live states (1 or 2).
-
Encode Intermediate States:
- 2: A cell transitions from live to dead.
- 3: A cell transitions from dead to live.
-
Finalize Updates:
- Traverse the matrix again to convert 2β0 and 3β1.
π Complexity Analysis
-
Time Complexity:
O(mβ n)
, wherem
is the number of rows andn
is the number of columns.- Each cell is visited twice: once to apply rules and once to finalize updates.
Space Complexity:
O(1)
, as the updates are performed in place.
π Dry Run
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]]
β¨ Pro Tips for Interviews
-
Explain Intermediate States:
- Highlight how encoding states avoids dependency issues during simultaneous updates.
-
Edge Cases:
- Single-row or single-column boards. Boards where all cells are live or all cells are dead.
-
Follow-Up:
- For infinite boards, consider tracking only the active area (cells with live neighbors).
π Learn More
Check out the full explanation and code walkthrough on my previous Dev.to post:
π Set Matrix Zeroes - JavaScript Solution
Whatβs your preferred method to solve this problem? Letβs discuss! π
Top comments (1)
Follow Me on GitHub π
If you found this solution helpful, check out more of my projects and solutions on my GitHub profile.
Don't forget to follow for more updates!
Some comments may only be visible to logged-in visitors. Sign in to view all comments.