LeetCode130. 被围绕的区域

思路1:DFS

  如果把X看作海水,O看作陆地,被海水包围的就是岛屿。没有被海水包围的陆地,与边界有连通,就不是岛屿。判断是否是岛屿比较困难,问题转化为先找出非岛屿(凡是与边界有联系的O),即对边界上的 O 特殊处理。根据题意,四个边的 0 以及与其相邻的 0 都不能被替换为X,因此从边界向里面扩展。解决步骤为:

    1)把四周有 0 的地方都替换为 “#”,在四周进行floodfill算法(染色)。 

    2)再从头到尾遍历矩阵,把 0 换成 X, 把“#”换成0.

 

思路2:BFS

思路3:并查集

 

代码1:

class Solution {
    public void solve(char[][] board) {
        if (board == null || board.length == 0) return;
        int m = board.length, n = board[0].length;
        // Step1:对边界上的O特殊处理,进行FloodFill
        //   难点:如何只遍历边界
//        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') {
//                        dfs(board, i, j);
//                    }
//                }
//            }
//        }
        // 遍历第一列 和 最后一列
        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);
        }
        // 遍历第一行 和  最后一行
        for (int i = 1; i < n - 1; i++) {
            if (board[0][i] == 'O') dfs(board, 0, i);
            if (board[m-1][i] == 'O') dfs(board, m-1, i);
        }
        // Step2:重新遍历矩阵,直接替换
        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] == '#') {
                    board[i][j] = 'O';
                }
            }
        }
    }
    // 思路同岛屿问题
    private void dfs(char[][] board, int x, int y) {
        if (x < 0 || x >= board.length || y < 0 || y >= board[0].length) return;
        if (board[x][y] != 'O') return;
        board[x][y] = '#';
        dfs(board, x - 1, y);
        dfs(board, x, y + 1);
        dfs(board, x + 1, y);
        dfs(board, x, y - 1);
    }
}

 

posted @ 2020-12-29 15:56  不学无墅_NKer  阅读(91)  评论(0编辑  收藏  举报