class Solution {
public:
vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) {
}
};
529. 扫雷游戏
让我们一起来玩扫雷游戏!
给你一个大小为 m x n
二维字符矩阵 board
,表示扫雷游戏的盘面,其中:
'M'
代表一个 未挖出的 地雷,'E'
代表一个 未挖出的 空方块,'B'
代表没有相邻(上,下,左,右,和所有4个对角线)地雷的 已挖出的 空白方块,'1'
到 '8'
)表示有多少地雷与这块 已挖出的 方块相邻,'X'
则表示一个 已挖出的 地雷。给你一个整数数组 click
,其中 click = [clickr, clickc]
表示在所有 未挖出的 方块('M'
或者 'E'
)中的下一个点击位置(clickr
是行下标,clickc
是列下标)。
根据以下规则,返回相应位置被点击后对应的盘面:
'M'
)被挖出,游戏就结束了- 把它改为 'X'
。'E'
)被挖出,修改它为('B'
),并且所有和其相邻的 未挖出 方块都应该被递归地揭露。'E'
)被挖出,修改它为数字('1'
到 '8'
),表示相邻地雷的数量。
示例 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] 输出:[["B","1","E","1","B"],["B","1","M","1","B"],["B","1","1","1","B"],["B","B","B","B","B"]]
示例 2:
输入:board = [["B","1","E","1","B"],["B","1","M","1","B"],["B","1","1","1","B"],["B","B","B","B","B"]], click = [1,2] 输出:[["B","1","E","1","B"],["B","1","X","1","B"],["B","1","1","1","B"],["B","B","B","B","B"]]
提示:
m == board.length
n == board[i].length
1 <= m, n <= 50
board[i][j]
为 'M'
、'E'
、'B'
或数字 '1'
到 '8'
中的一个click.length == 2
0 <= clickr < m
0 <= clickc < n
board[clickr][clickc]
为 'M'
或 'E'
原站题解
python3 解法, 执行用时: 64 ms, 内存消耗: 15.4 MB, 提交时间: 2022-11-28 14:48:18
class Solution: def updateBoard(self, board: List[List[str]], click: List[int]) -> List[List[str]]: i, j = click row, col = len(board), len(board[0]) if board[i][j] == "M": board[i][j] = "X" return board # 计算空白快周围的*** def cal(i, j): res = 0 for x in [1, -1, 0]: for y in [1, -1, 0]: if x == 0 and y == 0: continue if 0 <= i + x < row and 0 <= j + y < col and board[i + x][j + y] == "M": res += 1 return res def bfs(i, j): queue = collections.deque([[i, j]]) while queue: i, j = queue.pop() num = cal(i, j) if num > 0: board[i][j] = str(num) continue board[i][j] = "B" for x in [1, -1, 0]: for y in [1, -1, 0]: if x == 0 and y == 0: continue nxt_i, nxt_j = i + x, j + y if nxt_i < 0 or nxt_i >= row or nxt_j < 0 or nxt_j >= col: continue if board[nxt_i][nxt_j] == "E": queue.appendleft([nxt_i, nxt_j]) board[nxt_i][nxt_j] = "B" bfs(i, j) return board
python3 解法, 执行用时: 48 ms, 内存消耗: 19.1 MB, 提交时间: 2022-11-28 14:48:05
class Solution: def updateBoard(self, board: List[List[str]], click: List[int]) -> List[List[str]]: i, j = click row, col = len(board), len(board[0]) if board[i][j] == "M": board[i][j] = "X" return board # 计算空白快周围的*** def cal(i, j): res = 0 for x in [1, -1, 0]: for y in [1, -1, 0]: if x == 0 and y == 0: continue if 0 <= i + x < row and 0 <= j + y < col and board[i + x][j + y] == "M": res += 1 return res def dfs(i, j): num = cal(i, j) if num > 0: board[i][j] = str(num) return board[i][j] = "B" for x in [1, -1, 0]: for y in [1, -1, 0]: if x == 0 and y == 0: continue nxt_i, nxt_j = i + x, j + y if 0 <= nxt_i < row and 0 <= nxt_j < col and board[nxt_i][nxt_j] == "E": dfs(nxt_i, nxt_j) dfs(i, j) return board
golang 解法, 执行用时: 24 ms, 内存消耗: 6.5 MB, 提交时间: 2022-11-28 14:47:15
var dirX = []int{0, 1, 0, -1, 1, 1, -1, -1} var dirY = []int{1, 0, -1, 0, 1, -1, 1, -1} func updateBoard(board [][]byte, click []int) [][]byte { x, y := click[0], click[1] if board[x][y] == 'M' { board[x][y] = 'X' } else { bfs(board, x, y) } return board } func bfs(board [][]byte, sx, sy int) { queue := [][]int{} vis := make([][]bool, len(board)) for i := 0; i < len(vis); i++ { vis[i] = make([]bool, len(board[0])) } queue = append(queue, []int{sx, sy}) vis[sx][sy] = true for i := 0; i < len(queue); i++ { cnt, x, y := 0, queue[i][0], queue[i][1] for i := 0; i < 8; i++ { tx, ty := x + dirX[i], y + dirY[i] if tx < 0 || tx >= len(board) || ty < 0 || ty >= len(board[0]) { continue } // 不用判断 M,因为如果有 M 的话游戏已经结束了 if board[tx][ty] == 'M' { cnt++ } } if cnt > 0 { board[x][y] = byte(cnt + '0') } else { board[x][y] = 'B' for i := 0; i < 8; i++ { tx, ty := x + dirX[i], y + dirY[i] // 这里不需要在存在 B 的时候继续扩展,因为 B 之前被点击的时候已经被扩展过了 if tx < 0 || tx >= len(board) || ty < 0 || ty >= len(board[0]) || board[tx][ty] != 'E' || vis[tx][ty] { continue } queue = append(queue, []int{tx, ty}) vis[tx][ty] = true } } } }
golang 解法, 执行用时: 24 ms, 内存消耗: 6.9 MB, 提交时间: 2022-11-28 14:47:01
var dirX = []int{0, 1, 0, -1, 1, 1, -1, -1} var dirY = []int{1, 0, -1, 0, 1, -1, 1, -1} func updateBoard(board [][]byte, click []int) [][]byte { x, y := click[0], click[1] if board[x][y] == 'M' { board[x][y] = 'X' } else { dfs(board, x, y) } return board } func dfs(board [][]byte, x, y int) { cnt := 0 for i := 0; i < 8; i++ { tx, ty := x + dirX[i], y + dirY[i] if tx < 0 || tx >= len(board) || ty < 0 || ty >= len(board[0]) { continue } // 不用判断 M,因为如果有 M 的话游戏已经结束了 if board[tx][ty] == 'M' { cnt++ } } if cnt > 0 { board[x][y] = byte(cnt + '0') } else { board[x][y] = 'B' for i := 0; i < 8; i++ { tx, ty := x + dirX[i], y + dirY[i] // 这里不需要在存在 B 的时候继续扩展,因为 B 之前被点击的时候已经被扩展过了 if tx < 0 || tx >= len(board) || ty < 0 || ty >= len(board[0]) || board[tx][ty] != 'E' { continue } dfs(board, tx, ty) } } }