Let's play the minesweeper game! You are given an m x n
char matrix board
representing the game board where: 'M'
represents an unrevealed mine, 'E'
represents an unrevealed empty square, 'B'
represents a revealed blank square that has no adjacent mines, digit ('1'
to '8'
) represents how many mines are adjacent to this revealed square, and 'X'
represents a revealed mine. You are also given an integer array click
where click = [click_r, click_c]
represents the next click position among all the unrevealed squares ('M'
or 'E'
). Return the board after revealing this position according to the following rules: If a mine 'M'
is revealed, then the game is over. You should change it to 'X'
. If an empty square 'E'
with no adjacent mines is revealed, then change it to a revealed blank 'B'
and all of its adjacent unrevealed squares should be revealed recursively. If an empty square 'E'
with at least one adjacent mine is revealed, then change it to a digit ('1'
to '8'
) representing the number of adjacent mines. Return the board when no more squares will be revealed. For example, given board = [['E','E','E','E','E'],['E','E','M','E','E'],['E','E','E','E','E'],['E','E','E','E','E']]
and click = [3,0]
, the expected output is [['B','1','E','1','B'],['B','1','M','1','B'],['B','1','1','1','B'],['B','B','B','B','B']]
.
class Solution:
def updateBoard(self, board: list[list[str]], click: list[int]) -> list[list[str]]:
row, col = click
if board[row][col] == 'M':
board[row][col] = 'X'
return board
def count_adjacent_mines(r, c):
count = 0
for i in range(max(0, r - 1), min(len(board), r + 2)):
for j in range(max(0, c - 1), min(len(board[0]), c + 2)):
if (i, j) != (r, c) and board[i][j] == 'M':
count += 1
return count
def reveal(r, c):
if r < 0 or r >= len(board) or c < 0 or c >= len(board[0]) or board[r][c] != 'E':
return
mines = count_adjacent_mines(r, c)
if mines > 0:
board[r][c] = str(mines)
return
board[r][c] = 'B'
for i in range(max(0, r - 1), min(len(board), r + 2)):
for j in range(max(0, c - 1), min(len(board[0]), c + 2)):
if (i, j) != (r, c):
reveal(i, j)
reveal(row, col)
return board
The naive approach would be to iterate through the entire board for every click, which is not efficient. Instead, the given solution focuses on revealing only the necessary squares using Depth First Search (DFS).
The optimal solution employs a recursive DFS approach, revealing squares based on the game's rules. When an empty square is clicked, it checks the adjacent squares for mines. If no mines are adjacent, it reveals adjacent squares recursively.
count_adjacent_mines
function takes O(1) time since it checks at most 8 neighbors.reveal
. In the worst-case scenario, almost the entire board may be revealed which requires keeping the function calls on the stack.reveal
function.