Skip to content

Commit 49ee8d7

Browse files
Create 0529 - Minesweeper.md
Add Solution to leetcode problem 529 - Minesweeper
1 parent 6457ea7 commit 49ee8d7

File tree

1 file changed

+245
-0
lines changed

1 file changed

+245
-0
lines changed
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
---
2+
id: Minesweeper
3+
title: Minesweeper
4+
sidebar_label: Minesweeper
5+
tags:
6+
- matrix
7+
- recursion
8+
- BFS
9+
- game
10+
---
11+
12+
## Problem Description
13+
14+
| Problem Statement | Solution Link | LeetCode Profile |
15+
| :------------------------------------------------------ | :------------------------------------------------------------------------- | :------------------------------------------------------ |
16+
| [Minesweeper](https://leetcode.com/problems/Minesweeper/description/) | [Minesweeper Solution on LeetCode](https://leetcode.com/problems/Minesweeper/solutions/) | [Nikita Saini](https://leetcode.com/u/Saini_Nikita/) |
17+
18+
## Problem Description
19+
20+
You are given an m x n char matrix `board` representing a Minesweeper game board. The board consists of the following characters:
21+
- 'M' representing an unrevealed mine,
22+
- 'E' representing an unrevealed empty square,
23+
- 'B' representing a revealed blank square with no adjacent mines,
24+
- Digit ('1' to '8') representing how many mines are adjacent to this revealed square,
25+
- 'X' representing a revealed mine.
26+
27+
You are also given an integer array `click` where `click = [clickr, clickc]` represents the position of the next click among all unrevealed squares ('M' or 'E').
28+
29+
Return the board after revealing this position according to specific rules until no more squares will be revealed.
30+
31+
### Examples
32+
## Example 1
33+
**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]`
34+
**Output:** `[["B","1","E","1","B"],["B","1","M","1","B"],["B","1","1","1","B"],["B","B","B","B","B"]]`
35+
36+
## Example 2
37+
**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]`
38+
**Output:** `[["B","1","E","1","B"],["B","1","X","1","B"],["B","1","1","1","B"],["B","B","B","B","B"]]`
39+
40+
## Constraints
41+
42+
- `m == board.length`
43+
- `n == board[i].length`
44+
- `1 <= m, n <= 50`
45+
- `board[i][j]` is one of 'M', 'E', 'B', or a digit from '1' to '8'.
46+
- `click.length == 2`
47+
- `0 <= clickr < m`
48+
- `0 <= clickc < n`
49+
- `board[clickr][clickc]` is either 'M' or 'E'.
50+
51+
## Approach
52+
53+
The approach involves simulating the Minesweeper game board using either Depth-First Search (DFS) or Breadth-First Search (BFS):
54+
1. If the clicked cell is 'M', change it to 'X' and stop (game over).
55+
2. If the clicked cell is 'E' (empty), reveal it:
56+
- If it has no adjacent mines ('B'), recursively reveal all adjacent 'E' cells.
57+
- If it has adjacent mines, update it with the count of adjacent mines ('1' to '8').
58+
3. Use BFS or DFS to reveal adjacent cells based on the revealed cell's condition.
59+
4. Continue until no more cells can be revealed.
60+
61+
### Solution in Different Languages
62+
## Solution in Python
63+
64+
```python
65+
def updateBoard(board, click):
66+
m, n = len(board), len(board[0])
67+
directions = [(-1, 0), (1, 0), (0, -1), (0, 1), (-1, -1), (-1, 1), (1, -1), (1, 1)]
68+
69+
def count_adjacent_mines(row, col):
70+
count = 0
71+
for dr, dc in directions:
72+
nr, nc = row + dr, col + dc
73+
if 0 <= nr < m and 0 <= nc < n and board[nr][nc] == 'M':
74+
count += 1
75+
return count
76+
77+
def dfs(row, col):
78+
if not (0 <= row < m and 0 <= col < n) or board[row][col] != 'E':
79+
return
80+
num_mines = count_adjacent_mines(row, col)
81+
if num_mines > 0:
82+
board[row][col] = str(num_mines)
83+
else:
84+
board[row][col] = 'B'
85+
for dr, dc in directions:
86+
dfs(row + dr, col + dc)
87+
88+
click_r, click_c = click
89+
if board[click_r][click_c] == 'M':
90+
board[click_r][click_c] = 'X'
91+
else:
92+
dfs(click_r, click_c)
93+
return board
94+
```
95+
96+
## Solution in Java
97+
98+
```java
99+
class Solution {
100+
int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1}};
101+
102+
public char[][] updateBoard(char[][] board, int[] click) {
103+
int m = board.length, n = board[0].length;
104+
int row = click[0], col = click[1];
105+
106+
if (board[row][col] == 'M') {
107+
board[row][col] = 'X';
108+
} else {
109+
dfs(board, row, col);
110+
}
111+
112+
return board;
113+
}
114+
115+
private void dfs(char[][] board, int row, int col) {
116+
int m = board.length, n = board[0].length;
117+
if (row < 0 || row >= m || col < 0 || col >= n || board[row][col] != 'E') return;
118+
119+
int mines = countAdjacentMines(board, row, col);
120+
if (mines > 0) {
121+
board[row][col] = (char) (mines + '0');
122+
} else {
123+
board[row][col] = 'B';
124+
for (int[] dir : dirs) {
125+
dfs(board, row + dir[0], col + dir[1]);
126+
}
127+
}
128+
}
129+
130+
private int countAdjacentMines(char[][] board, int row, int col) {
131+
int m = board.length, n = board[0].length;
132+
int count = 0;
133+
for (int[] dir : dirs) {
134+
int r = row + dir[0];
135+
int c = col + dir[1];
136+
if (r >= 0 && r < m && c >= 0 && c < n && board[r][c] == 'M') {
137+
count++;
138+
}
139+
}
140+
return count;
141+
}
142+
}
143+
```
144+
145+
## Solution in C++
146+
147+
```cpp
148+
class Solution {
149+
public:
150+
vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) {
151+
int m = board.size(), n = board[0].size();
152+
vector<vector<int>> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1}};
153+
154+
function<int(int, int)> countAdjacentMines = [&](int row, int col) {
155+
int count = 0;
156+
for (auto& dir : directions) {
157+
int nr = row + dir[0], nc = col + dir[1];
158+
if (nr >= 0 && nr < m && nc >= 0 && nc < n && board[nr][nc] == 'M') {
159+
count++;
160+
}
161+
}
162+
return count;
163+
};
164+
165+
function<void(int, int)> dfs = [&](int row, int col) {
166+
if (row < 0 || row >= m || col < 0 || col >= n || board[row][col] != 'E') return;
167+
168+
int numMines = countAdjacentMines(row, col);
169+
if (numMines > 0) {
170+
board[row][col] = '0' + numMines;
171+
} else {
172+
board[row][col] = 'B';
173+
for (auto& dir : directions) {
174+
dfs(row + dir[0], col + dir[1]);
175+
}
176+
}
177+
};
178+
179+
int click_r = click[0], click_c = click[1];
180+
if (board[click_r][click_c] == 'M') {
181+
board[click_r][click_c] = 'X';
182+
} else {
183+
dfs(click_r, click_c);
184+
}
185+
186+
return board;
187+
}
188+
};
189+
```
190+
191+
## Solution in JavaScript
192+
193+
```javascript
194+
var updateBoard = function(board, click) {
195+
const m = board.length, n = board[0].length;
196+
const directions = [[-1, 0], [1, 0], [0, -1], [0, 1], [-1, -1], [-1, 1], [1, -1], [1, 1]];
197+
198+
function countAdjacentMines(row, col) {
199+
let count = 0;
200+
for (const [dr, dc] of directions) {
201+
const nr = row + dr, nc = col + dc;
202+
if (nr >= 0 && nr < m && nc >= 0 && nc < n && board[nr][nc] === 'M') {
203+
count++;
204+
}
205+
}
206+
return count;
207+
}
208+
209+
function dfs(row, col) {
210+
if (row < 0 || row >= m || col < 0 || col >= n || board[row][col] !== 'E') return;
211+
212+
const numMines = countAdjacentMines(row, col);
213+
if (numMines > 0) {
214+
board[row][col] = numMines.toString();
215+
} else {
216+
board[row][col] = 'B';
217+
for (const [dr, dc] of directions) {
218+
dfs(row + dr, col + dc);
219+
}
220+
}
221+
}
222+
223+
const [click_r, click_c] = click;
224+
if (board[click_r][click_c] === 'M') {
225+
board[click_r][click_c] = 'X';
226+
} else {
227+
dfs(click_r, click_c);
228+
}
229+
230+
return board;
231+
};
232+
```
233+
234+
## Step-by-Step Algorithm
235+
236+
1. **Initialize Directions**: Define the eight possible directions (including diagonals) for exploring adjacent cells.
237+
2. **Count Adjacent Mines**: Implement a function to count adjacent mines for a given cell.
238+
3. **DFS or BFS**: Use DFS (Depth-
239+
240+
First Search) or BFS (Breadth-First Search) to reveal cells based on the rules of the Minesweeper game.
241+
4. **Edge Cases**: Handle edge cases like clicking on a mine ('M') which ends the game, or revealing adjacent cells recursively until no more can be revealed.
242+
243+
## Conclusion
244+
245+
This solution effectively simulates the Minesweeper game mechanics using recursion (DFS) or iteration (BFS) to reveal cells and update the game board accordingly. By following the rules provided and implementing efficient traversal methods, the solution ensures that all valid scenarios are covered, including game over conditions and successful completion of the game board reveal.

0 commit comments

Comments
 (0)