130.被围绕的区域
给定一个二维的矩阵,包含 'X' 和 'O'(字母 O)。
找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。
示例:
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'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
思路:
• 只有边界上的 'O' 字母,以及与边界上的 'O' 上下左右相邻的 'O',才不会被包围替换;
• 遍历给定的矩阵,满足边界,且字母为 O时,开始深搜与之相邻的 O;
• 标记与之相邻的 O,标记为 A,表示:与边界相邻,未被包围,且已经遍历过了;
• 所有边界都遍历完后,对矩阵进行 替换、还原的操作。
class Solution { public void solve(char[][] board) { if(board.length == 0 || board[0].length == 0) return; int m = board.length, n = board[0].length; for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ boolean isEdge = (i == 0 || i == m-1 || j == 0 || j == n-1);//是否为边界 if(isEdge && board[i][j] == 'O') DFS(board, i, j); //边界,且当前字母为 'O',开始深搜 } } for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ if(board[i][j] == 'X') continue; else if(board[i][j] == 'O') board[i][j] = 'X'; //未被标记过的 O,表示被包围了,替换为 X else if(board[i][j] == 'A') board[i][j] = 'O'; //标记过的O,与边界相邻,未包围,还原为 O } } } private void DFS(char[][] board, int x, int y){ if(x < 0 || x >= board.length || y < 0 || y >= board[0].length || board[x][y] == 'X' || board[x][y] == 'A') return; board[x][y] = 'A'; //深搜时,与边界上的 O 相邻,标记为走过 DFS(board,x-1, y);//上 DFS(board,x+1, y);//下 DFS(board,x, y-1);//左 DFS(board,x, y+1);//右 } }