130. Surrounded Regions
Given an m x n
matrix board
containing 'X'
and 'O'
, capture all regions that are 4-directionally surrounded by 'X'
.
A region is captured by flipping all 'O'
s into 'X'
s in that surrounded region.
Example 1:
Input: board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]
Output: [["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]
Explanation: Notice that an 'O' should not be flipped if:
- It is on the border, or
- It is adjacent to an 'O' that should not be flipped.
The bottom 'O' is on the border, so it is not flipped.
The other three 'O' form a surrounded region, so they are flipped.
My Solutions:
方法1:DFS
只有在边界上的‘O’是肯定不会被X包围的,因此从边界上的所有 ‘O’ 着手,以他们为起点做dfs,找到所有与他们连通的 ‘O’ ,并将他们替换为其他字符比如 ‘A’。这样操作完所有格子后,没有被改变过的 ‘O’ 一定是被 ‘X’ 包围的所以无法被改变。
最后再遍历一遍矩阵上每一个点,遇到 ‘O’ 时替换为 ‘X’,遇到 ‘A’时还原为 ‘O’ 。
public void solve(char[][] board) {
int m = board.length, n = board[0].length;
// 对每一行,遍历在column左右边界上的‘O’
for (int i = 0; i < m; i++) {
if (board[i][0] == 'O') dfs(board, i, 0);
if (board[i][n - 1] == 'O') dfs(board, i, n - 1);
}
// 对每一列,遍历在row上下边界上的‘O’
for (int i = 0; i < n; i++) {
if (board[0][i] == 'O') dfs(board, 0, i);
if (board[m - 1][i] == 'O') dfs(board, m - 1, i);
}
// change 'O' to 'X' and restore 'A' to 'O'
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == 'O') board[i][j] = 'X';
else if (board[i][j] == 'A') board[i][j] = 'O';
}
}
}
private void dfs(char[][] board, int i, int j) {
int m = board.length, n = board[0].length;
// 注意这里是i>=m和j>=n,因为这两种情况是不允许的
if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O') return;
board[i][j] = 'A';
dfs(board, i + 1, j);
dfs(board, i - 1, j);
dfs(board, i, j + 1);
dfs(board, i, j - 1);
}
方法2:BFS
DFS容易导致栈溢出,用BFS不会有这个问题。
public void solve(char[][] board) {
int m = board.length, n = board[0].length;
Queue<int[]> q = new LinkedList<>(); // 用来储存格子坐标
// 遍历在column和row边界上的‘O’
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (i == 0 || i == m - 1 || j == 0 || j == n - 1) {
if (board[i][j] == 'O') {
q.offer(new int[]{i, j}); // 把O的格子加入q
board[i][j] = 'A'; // O格子变成A
}
}
}
}
int[] dx = new int[]{0, 0, -1, 1};
int[] dy = new int[]{-1, 1, 0, 0};
while (!q.isEmpty()) {
int[] cell = q.poll();
int row = cell[0], col = cell[1];
// 遍历所有存下来的O格子的四个方向
for (int i = 0; i < 4; i++) {
int r = row + dx[i], c = col + dy[i];
if (r < 0 || r >= m || c < 0 || c >= n || board[r][c] != 'O') continue;
board[r][c] = 'A'; // 改变O格子为A
q.offer(new int[]{r, c});
}
}
// change 'O' to 'X' and restore 'A' to 'O'
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == 'O') board[i][j] = 'X';
else if (board[i][j] == 'A') board[i][j] = 'O';
}
}
}
Last updated