被围绕的区域
难度:
标签:
题目描述
给你一个
m x n
的矩阵 board
,由若干字符 'X'
和 'O'
,找到所有被 'X'
围绕的区域,并将这些区域里所有的 'O'
用 'X'
填充。
示例 1:
输入:board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]] 输出:[["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]] 解释:被围绕的区间不会存在于边界上,换句话说,任何边界上的'O'
都不会被填充为'X'
。 任何不在边界上,或不与边界上的'O'
相连的'O'
最终都会被填充为'X'
。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
示例 2:
输入:board = [["X"]] 输出:[["X"]]
提示:
m == board.length
n == board[i].length
1 <= m, n <= 200
board[i][j]
为'X'
或'O'
代码结果
运行时间: 20 ms, 内存: 20.5 MB
/*
思路:
使用Stream API来处理二维数组的操作。因为Stream API不直接支持二维数组操作,这里主要是通过传统遍历后转换为Stream来实现
*/
import java.util.stream.Stream;
import java.util.stream.IntStream;
public class SolutionStream {
public void solve(char[][] board) {
if (board == null || board.length == 0) return;
int m = board.length;
int n = board[0].length;
// 标记边界上的'O'以及与其相连的'O'
Stream.concat(
IntStream.range(0, m).boxed(),
IntStream.range(0, n).boxed()
).forEach(i -> {
if (i < m && board[i][0] == 'O') dfs(board, i, 0);
if (i < m && board[i][n - 1] == 'O') dfs(board, i, n - 1);
if (i < n && board[0][i] == 'O') dfs(board, 0, i);
if (i < n && board[m - 1][i] == 'O') dfs(board, m - 1, i);
});
// 将所有的'O'变为'X'
IntStream.range(0, m).forEach(i ->
IntStream.range(0, n).forEach(j -> {
if (board[i][j] == 'O') board[i][j] = 'X';
})
);
// 将所有的'*'还原为'O'
IntStream.range(0, m).forEach(i ->
IntStream.range(0, n).forEach(j -> {
if (board[i][j] == '*') board[i][j] = 'O';
})
);
}
// 深度优先搜索,标记与边界'O'相连的'O'
private void dfs(char[][] board, int i, int j) {
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] != 'O') return;
board[i][j] = '*';
dfs(board, i + 1, j);
dfs(board, i - 1, j);
dfs(board, i, j + 1);
dfs(board, i, j - 1);
}
}
解释
方法:
这个题解采用了深度优先搜索(DFS)的方法。首先对矩阵的四条边界上的 'O' 进行 DFS,标记所有与边界 'O' 相连的 'O',这些 'O' 不会被填充为 'X'。然后遍历矩阵内部,将所有未被标记的 'O' 填充为 'X'。
时间复杂度:
O(mn)
空间复杂度:
O(mn)
代码细节讲解
🦆
题解中提到的DFS的递归深度最大为m+n,请问这是如何算出来的?是否有可能超过这个深度?
▷🦆
在DFS中,为什么需要判断`visited[row][col]`值为False才进行递归搜索?
▷🦆
题解提到对四条边界上的'O'进行DFS,为什么这种策略能确保所有与边界相连的'O'都不会被填充为'X'?
▷🦆
如果矩阵的尺寸非常大,DFS可能会导致栈溢出。是否有其他方法可以避免这种情况?
▷相关问题
岛屿数量
给你一个由 '1'
(陆地)和 '0'
(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:grid = [ ["1","1","1","1","0"], ["1","1","0","1","0"], ["1","1","0","0","0"], ["0","0","0","0","0"] ] 输出:1
示例 2:
输入:grid = [ ["1","1","0","0","0"], ["1","1","0","0","0"], ["0","0","1","0","0"], ["0","0","0","1","1"] ] 输出:3
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 300
grid[i][j]
的值为'0'
或'1'