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);//
    }
}
原文地址:https://www.cnblogs.com/luo-c/p/13848274.html