9.18 DFS 中等 130 Surrounded Regions 【搭配200食用更佳】

130 Surrounded Regions【思路简化】

在这里插入图片描述

class Solution {
public:
    bool DFS(vector<vector<char>>& board,vector<vector<int>>& signal,int i , int j){
        int m = board.size();
        int n = board[0].size();
        //区域条件:在区域内、为O、没有探索过
        if(i<0 || j<0 || i>m-1 || j >n-1 || board[i][j] == 'X' || signal[i][j] == 1) return false;
        //标记
        signal[i][j] = 1;

        //会出现区域与边缘接壤的情况,这片区域就废了,不能用'X'覆盖
        if(i == 0 || i == m-1 || j == 0 || j == n-1) return false;
        
        
        //up
        DFS(board , signal ,i-1 ,j);
        //down
        DFS(board , signal ,i+1 ,j);
        //left
        DFS(board , signal ,i ,j-1);
        //right
        DFS(board , signal ,i ,j+1);

        return true;

    }
    void solve(vector<vector<char>>& board) {
        //m*n的matrix,包含X 或 O字符,捕捉被围绕的区域:
        //将捕捉区域用'X'进行覆盖
        //所以需要明确被捕捉区域:上下左右被X包围,且没有区域在matrix的边缘位置
        //判断捕捉条件 & 不能改变board
        int m = board.size();
        int n = board[0].size();
        //用于标记该位置需要被捕捉
        vector<vector<int>> signal(m , vector<int>(n,0));
        for(int i = 0 ; i < m ; i++){
            for(int j = 0 ; j < n ; j++){
                if(board[i][j] == 'O'){
                //如果返回true,说明不与边缘接壤,就可以进一步标记
                //按理来说每个O都能找到所在区域的边缘并判断是否在matrix的边上
                //但是,DFS中的过滤条件中包括了 不能标记已经被探索过的区域 否则返回false
                //所以如果一个O已经探索完一个区域,再次进入该区域时的O都会别返还FALSE就出错了!!!!
                    if(DFS(board , signal ,i ,j))signal[i][j] = 2;
                }
            }
        }
        //进行捕捉
        for(int i = 0 ; i < m ; i++){
            for(int j = 0 ; j < n ; j++){
                if(signal[i][j] == 2){
                    board[i][j] = 'X';
                }
            }
        }
    }
};

问题分析: 如果返回true,说明不与边缘接壤,就可以进一步标记;按理来说每个O都能找到所在区域的边缘并判断是否在matrix的边上;但是,DFS中的过滤条件中包括了 不能标记已经被探索过的区域 否则返回false;所以如果一个O已经探索完一个区域,再次进入该区域时的O都会别返还FALSE就出错了!!!!
问题解决:solve中不能直接一个个遍历,需要先边缘遍历,将边缘区域都找出来,标记为O X 以外的任意字符,后面直接遍历board将之前标记的字符转化为O,将O转化为X

class Solution {
public:
    void DFS(vector<vector<char>>& board,int i , int j){
        int m = board.size();
        int n = board[0].size();
        // 区域条件: 在区域内、为O
        if(i < 0 || j < 0 || i >= m || j >= n || board[i][j] != 'O') return;
        //标记
        board[i][j] = '#';

        
        //up
        DFS(board  ,i-1 ,j );
        //down
        DFS(board ,i+1 ,j);
        //left
        DFS(board ,i ,j-1);
        //right
        DFS(board ,i ,j+1);


    }
    void solve(vector<vector<char>>& board) {
        //m*n的matrix,包含X 或 O字符,捕捉被围绕的区域:
        //将捕捉区域用'X'进行覆盖
        //所以需要明确被捕捉区域:上下左右被X包围,且没有区域在matrix的边缘位置
        
        int m = board.size();
        int n = board[0].size();
        //行变
        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 j = 0 ; j < n ; j++){
            if(board[0][j] == 'O'){
                DFS(board , 0 , j  );
            }
            if(board[m-1][j] == 'O'){
                DFS(board , m-1 , j  );
            }
        }
        //剩余区域探索,只要为O变X
        //进行捕捉
        for(int i = 0 ; i < m ; i++){
            for(int j = 0 ; j < n ; j++){
                if(board[i][j] == 'O'){
                    board[i][j] = 'X';
                }
                if(board[i][j] == '#'){
                     board[i][j] = 'O';
                }
            }
        }
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值