Leetcode.130. 被围绕的区域---DFS+标记法(反面出发一招致命)

130. 被围绕的区域

给你一个 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'

题解:

通过观察我们发现,我们的目标是修改所有‘X’‘O’中,被‘X’包围的所有‘O’。那么怎么判定是否被包围呢?通过观察,我们发现,一旦有‘O’的区域是不被包围的,则代表这片‘O’区域一定会和区域的边界连接,一旦会连接,则代表边界上是有‘O’的,这样才可导致其不被包围,反之则一定会被包围。

得到此关键因素后,我们就可以容易的想出以下思路:

  1. 先对边界进行遍历查找,查找是否有‘O’的元素;
  2. 对在边界上查找到的‘O’,进行dfs查找,将与其连续的都查找出来,并将这些区域都改为‘N’,代表其是不被包围的‘O’区域;
  3. 边界查找完毕后,我们重新遍历整个区域,一旦发现还是有‘O’存在,则一定是被包围的‘O’区域,因此直接改为‘X’即可,因为没有被包围‘O’区域的我们都改写为了‘N’
  4. 对所有的‘N’进行还原,还原为‘O’

主体思路就是先找出不被包围的‘O’区域,将他们做上标记,接着遍历数组碰到‘O’就改成‘X’即可,即可完成对被包围区域的重新填充,最后再还原标记即可。先从不被包围的‘O’区域入手是因为其好找,一定起点在边界出发。

JAVA代码:

class Solution {
    public void solve(char[][] board) {
        for(int i=0;i<board[0].length;i++){
            if(board[0][i]=='O'){
                dfs(board,0,i);
            }
        }   
        for(int i=0;i<board.length;i++){
            if(board[i][board[0].length-1]=='O'){
                dfs(board,i,board[0].length-1);
            }
        }   
        for(int i=0;i<board[0].length;i++){
            if(board[board.length-1][i]=='O'){
                dfs(board,board.length-1,i);
            }
        }   
        for(int i=0;i<board.length;i++){
            if(board[i][0]=='O'){
                dfs(board,i,0);
            }
        }
        for(int i=0;i<board.length;i++){
            for(int j=0;j<board[0].length;j++){
                if(board[i][j]=='O'){
                    board[i][j]='X';
                }
                if(board[i][j]=='N'){
                    board[i][j]='O';
                }
            }
        }
          
    }

    public void dfs(char[][] board,int i,int j){
        if(i<0 || j<0 ||
            i>board.length-1 || j>board[0].length-1 || board[i][j]!='O'){
            return;
        }

        board[i][j] = 'N';

        dfs(board,i+1,j);
        dfs(board,i,j+1);
        dfs(board,i-1,j);
        dfs(board,i,j-1);

    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向光.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值