Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'.
A region is captured by flipping all 'O's into 'X's in that surrounded region.
For example,
X X X X
X O O X
X X O X
X O X X
After running your function, the board should be:
X X X X
X X X X
X X X X
X O X X
[分析] 使用DFS在大数据时会stackoverflow, 因此选择BFS。边界上的O不会变为 X,因此对边界上各元素进行BFS,BFS搜索时遇到的 O 均从边界 O可达,因此将不翻转,将已搜索过的 O 标记为特殊字符比如 M 以避免重复搜索死循环。搜索完成后所有剩余的 O 均需翻转,并将所有 M 恢复为 O。 BFS搜索时队列中维护的是所有未展开BFS的 O,队列记录这些 O的位置。
public class Solution {
public void solve(char[][] board) {
if (board == null || board.length == 0 || board[0].length == 0) return;
int rows = board.length, cols = board[0].length;
for (int i = 0; i < rows; i++) {
bfs(i, 0, board);
bfs(i, cols - 1, board);
}
for (int j = 0; j < cols; j++) {
bfs(0, j, board);
bfs(rows - 1, j, board);
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (board[i][j] == 'M')
board[i][j] = 'O';
else if (board[i][j] == 'O')
board[i][j] = 'X';
}
}
}
private void bfs(int i, int j, char[][] board) {
LinkedList<Integer> queue = new LinkedList<Integer>();
visit(i, j, board, queue);
while (!queue.isEmpty()) {
int idx = queue.poll();
int r = idx / board[0].length;
int c = idx % board[0].length;
visit(r + 1, c, board, queue);
visit(r - 1, c, board, queue);
visit(r, c - 1, board, queue);
visit(r, c + 1, board, queue);
}
}
private void visit(int i, int j, char[][] board, LinkedList<Integer> queue) {
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] != 'O')
return;
board[i][j] = 'M';
queue.offer(i * board[0].length + j);
}
}