题目地址:
https://www.lintcode.com/problem/minesweeper/description
想象一个扫雷游戏,给定一个字符型二维矩阵
A
A
A,如果某个位置
A
[
i
]
[
j
]
=
E
A[i][j]=E
A[i][j]=E则代表的是未发现的空地,如果
A
[
i
]
[
j
]
=
B
A[i][j]=B
A[i][j]=B,则代表已发现的空地,如果
A
[
i
]
[
j
]
=
M
A[i][j]=M
A[i][j]=M,则代表是地雷,如果
A
[
i
]
[
j
]
A[i][j]
A[i][j]是数字,则代表其八个邻居里地雷的数量。再给定一个位置
(
x
,
y
)
(x,y)
(x,y),题目保证
A
[
x
]
[
y
]
A[x][y]
A[x][y]是
M
M
M或者
E
E
E。假设某人在这个位置用鼠标点了一下,接下来矩阵会按照下面的方式更新:
1、如果点到了
M
M
M上,则将该
M
M
M变为
X
X
X;
2、如果点到了
E
E
E上,分两种情况讨论,如果该
E
E
E的八个邻居里有地雷,则将该
E
E
E改为地雷数量;否则,将其改为
B
B
B,并递归修改其八个邻居里的
E
E
E方块。
返回点击后的矩阵。
思路是DFS。直接模拟修改过程即可。代码如下:
public class Solution {
/**
* @param board: a board
* @param click: the position
* @return: the new board
*/
public char[][] updateBoard(char[][] board, int[] click) {
// Write your code here
int x = click[0], y = click[1];
if (board[x][y] == 'M') {
board[x][y] = 'X';
return board;
}
int count = count(board, x, y);
if (count != 0) {
board[x][y] = (char) ('0' + count);
return board;
}
dfs(x, y, board);
return board;
}
private void dfs(int x, int y, char[][] board) {
int count = count(board, x, y);
if (count > 0) {
board[x][y] = (char) ('0' + count);
return;
}
board[x][y] = 'B';
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (i == 0 && j == 0) {
continue;
}
int nextX = x + i, nextY = y + j;
if (inBound(nextX, nextY, board) && board[nextX][nextY] == 'E') {
dfs(nextX, nextY, board);
}
}
}
}
// 返回board[x][y]的八个邻居有多少个地雷
private int count(char[][] board, int x, int y) {
int res = 0;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (i == 0 && j == 0) {
continue;
}
int nextX = x + i, nextY = y + j;
if (inBound(nextX, nextY, board) && board[nextX][nextY] == 'M') {
res++;
}
}
}
return res;
}
private boolean inBound(int x, int y, char[][] board) {
return 0 <= x && x < board.length && 0 <= y && y < board[0].length;
}
}
时空复杂度 O ( m n ) O(mn) O(mn)。