529. Minesweeper - Detailed Explanation
Problem Statement
Description:
You are given a 2D board representing a Minesweeper game. Each cell on the board can be one of the following characters:
'M'– an unrevealed mine,'E'– an unrevealed empty square,'B'– a revealed blank square with no adjacent mines,'1'to'8'– a revealed square indicating the number of adjacent mines,'X'– a revealed mine (game over).
You are also given a click position (a pair of row and column indices). Based on the click, update the board as follows:
- Mine Clicked:
If a mine ('M') is clicked, change it to'X'to mark that the game is over. - Empty Square Clicked (No Adjacent Mines):
If an empty square ('E') with no adjacent mines is revealed, change it to a blank ('B'). Then, recursively reveal all of its adjacent unrevealed squares. - Empty Square Clicked (With Adjacent Mines):
If an empty square ('E') with one or more adjacent mines is revealed, change it to a digit ('1'to'8') representing the number of adjacent mines. - Stop Condition:
Return the updated board when no more squares can be revealed.
Examples:
-
Example 1:
Input:
board = [['E', 'E', 'E', 'E', 'E'], ['E', 'E', 'M', 'E', 'E'], ['E', 'E', 'E', 'E', 'E'], ['E', 'E', 'E', 'E', 'E']] click = [3, 0]Output:
[['B', '1', 'E', '1', 'B'], ['B', '1', 'M', '1', 'B'], ['B', '1', '1', '1', 'B'], ['B', 'B', 'B', 'B', 'B']]Explanation:
The click at position[3, 0](bottom-left corner) reveals an empty square with no adjacent mines. A recursive reveal then occurs to all adjacent squares. For squares adjacent to a mine, the count is shown. -
Example 2:
Input:
board = [['B', '1', 'E', '1', 'B'], ['B', '1', 'M', '1', 'B'], ['B', '1', '1', '1', 'B'], ['B', 'B', 'B', 'B', 'B']] click = [1, 2]Output:
[['B', '1', 'E', '1', 'B'], ['B', '1', 'X', '1', 'B'], ['B', '1', '1', '1', 'B'], ['B', 'B', 'B', 'B', 'B']]Explanation:
The click at position[1, 2]hits a mine. The mine is then revealed as'X', indicating game over.
Constraints:
- The board is a 2D array of characters.
- The click is a valid coordinate within the board.
- Board dimensions and the number of mines/empty squares vary, but you can assume the board is not empty.
Hints Before Diving into the Solution
-
Hint 1:
Think about how you can explore the board in all 8 directions (up, down, left, right, and the 4 diagonals) from any given cell. This is crucial for counting adjacent mines and for the recursive reveal. -
Hint 2:
When revealing cells, consider using either Depth-First Search (DFS) or Breadth-First Search (BFS). What conditions will determine whether you should stop the search in a certain direction?
Approach 1: Depth-First Search (DFS)
Idea:
-
Click a Mine:
If the clicked cell is'M', update it to'X'and return immediately. -
Reveal an Empty Cell:
If the clicked cell is'E', count the number of adjacent mines by exploring all 8 directions.- No Adjacent Mines:
If the count is zero, change the cell to'B'and recursively reveal all adjacent unrevealed cells. - Adjacent Mines Present:
If the count is greater than zero, update the cell with the count (as a character) and stop further exploration from that cell.
- No Adjacent Mines:
Visual Walkthrough:
Imagine a cell at position (i, j). For each of the 8 directions (e.g., (i-1, j), (i+1, j), (i, j-1), (i, j+1), and the four diagonals), check if the cell contains a mine ('M').
- If zero mines are adjacent, mark it as
'B'and perform DFS on its neighbors. - If there are mines present, update the cell with the number of mines and do not explore its neighbors.
Approach 2: Breadth-First Search (BFS)
Idea:
- Use a Queue:
Start by adding the clicked cell to a queue. - Process Each Cell:
While the queue is not empty:- Remove a cell from the queue.
- If it is an empty cell (
'E'), count adjacent mines. - If the count is zero, mark the cell as
'B'and enqueue all adjacent unrevealed cells. - Otherwise, update the cell with the count.
- Stop When Done:
Continue until there are no cells left to process in the queue.
Comparison:
- DFS is naturally recursive and might be easier to implement, but it could run into deep recursion issues on large boards.
- BFS uses an iterative approach with a queue, which can help avoid recursion depth problems and might be preferred when the board is large.
Python Code
Java Code
Complexity Analysis
-
Time Complexity:
In the worst-case scenario, you might end up visiting every cell once. Hence, the time complexity is O(m * n), where m is the number of rows and n is the number of columns. -
Space Complexity:
- For DFS, the recursion stack may go as deep as O(m * n) in the worst case.
- For BFS (if implemented), you’d use additional space for the queue but it would also be O(m * n).
- The board itself is modified in place, so extra space is minimal beyond recursion/queue.
Step-by-Step Walkthrough & Visual Example
Consider Example 1:
board = [['E', 'E', 'E', 'E', 'E'],
['E', 'E', 'M', 'E', 'E'],
['E', 'E', 'E', 'E', 'E'],
['E', 'E', 'E', 'E', 'E']]
click = [3, 0]
-
Click Handling:
The click is on[3, 0], which is'E'. Since it’s not a mine, we start our DFS. -
Counting Adjacent Mines at [3,0]:
Check all 8 directions. If no mines are found, mark[3,0]as'B'and recursively process its neighbors. -
Recursive Reveal:
Continue this process for every cell reached. When a cell has adjacent mines, update that cell with the count (for example, if there is one adjacent mine, it becomes'1') and do not expand further from that cell. -
Termination:
The recursion stops when all reachable cells have either been marked as'B'or updated with a digit. The final board is then returned.
Common Mistakes
-
Not Checking Boundaries:
When iterating over adjacent cells, always ensure you do not access indices outside the board. -
Overlapping Recursion:
Failing to update a cell immediately after processing can lead to repeated DFS calls on the same cell. Make sure to update and then mark cells to avoid cycles. -
Incorrect Direction Handling:
It’s important to cover all 8 directions. Omitting one or miscalculating an adjacent index can lead to wrong mine counts.
Edge Cases & Alternative Variations
-
Edge Case 1:
Clicking on a mine (cell'M'). The expected behavior is to update that cell to'X'immediately. -
Edge Case 2:
A board where all cells are already revealed or have no unrevealed cells left. Although not common, ensure your solution gracefully handles such cases. -
Alternative Variation:
Some variations might require counting adjacent mines differently (for example, considering only four directions instead of eight). Adjust the direction array accordingly.
Related Problems for Further Practice
- Flood Fill:
Similar recursive expansion of cells based on conditions. - Number of Islands:
Use DFS/BFS to traverse 2D grids. - Walls and Gates:
Propagate distances in a 2D grid. - Game of Life:
Update board states based on neighboring cell counts.
GET YOUR FREE
Coding Questions Catalog
$197

$78
$78