这个题目还是一道模版题,我这里用的是bfs实现,
实现的要点:
-
这个题的bfs 是图的bfs 不是二叉树的bfs,所以一定要有一个visited 来标记之前访问过的节点 不然很容易就死循环了
-
上下左右以及对角线4个点 一共是8个方向 可以用2个数组来实现, 这样逻辑上可以更清晰
3.这个题虽然我做出来了,但是也有没想通的地方
例如上图中 为啥结果会有一个E 没有被点出来? 这里难道不应该是一个1吗?
public char[][] updateBoard(char[][] board, int[] click) {
int rowSize = board.length;
int colSize = board[0].length;
// 如果挖到地雷就直接结束
if (board[click[0]][click[1]] == 'M') {
board[click[0]][click[1]] = 'X';
return board;
}
boolean[][] visited = new boolean[rowSize][colSize];
Queue<int[]> queue = new LinkedList<>();
queue.offer(click);
// 图的bfs一定要有visited 否则可能会一直在循环里走不出来
visited[click[0]][click[1]] = true;
//左上,上 ,右上,左,右,左下,右下,下
int[] dRow = {-1, -1, -1, 0, 0, 1, 1, 1};
int[] dCol = {-1, 0, 1, -1, 1, -1, 1, 0};
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
int[] cur = queue.poll();
// 如果挖到空地
// 默认的相邻地块为地雷的数量
int mSize = 0;
for (int j = 0; j < 8; j++) {
int r = cur[0] + dRow[j];
int c = cur[1] + dCol[j];
if (r < 0 || c < 0 || r >= rowSize || c >= colSize) {
continue;
}
if (board[r][c] == 'M') {
mSize++;
}
}
if (mSize != 0) {
board[cur[0]][cur[1]] = (mSize + "").toCharArray()[0];
} else {
board[cur[0]][cur[1]] = 'B';
for (int j = 0; j < 8; j++) {
int r = cur[0] + dRow[j];
int c = cur[1] + dCol[j];
if (r < 0 || c < 0 || r >= rowSize || c >= colSize || visited[r][c] || board[r][c] != 'E') {
continue;
}
queue.offer(new int[]{r, c});
visited[r][c] = true;
}
}
}
}
return board;
}