LeetCode130. 被围绕的区域(回溯 , DFS)

力扣

 

解题思路:

本题的意思被包围的区间不会存在于边界上,所以边界上的 o 以及与 o 联通的都不算做包围,只要把边界上的 o 以及与之联通的 o 进行特殊处理,剩下的o 替换成 x 即可。故问题转化为,如何寻找和边界联通的 o ,我们需要考虑如下情况。
                        
从每一个边缘的 o 开始,只要和边缘的 o 联通,则它就没有被包围。
                
1. 首先寻找边上的每一个 o ,如果没有,表示所有的 o 都被包围
2. 对于边上的每一个 o 进行 dfs 进行扩散,先把边上的每一个 o 用特殊符号标记,比如 * # 等,
3. 把和它相邻的 o 都替换为特殊符号,每一个新的位置都做相同的 dfs 操作
4. 所有扩散结束之后,把特殊符号的位置(和边界连通)还原为 o, 原来为 o 的位置(和边界不连通)替换为 x 即可。
这里一定要注意这里是大'O' 和大 'X'

                                       

class Solution {
public:
    int dir[4][2] = {1 , 0 , -1 , 0 , 0 , -1 , 0 , 1};

    void DFS(vector<vector<char>>& board , int row , int col , int x , int y )
    {
          board[x][y] = 'M'; //边界上与O 相连的特殊设置

       for(auto& e : dir)
       {
           int newx = x + e[0];
           int newy = y + e[1];

           if(newx < 0 || newx >= row || newy < 0 || newy >=col || board[newx][newy] != 'O')
             continue;  //是否满足搜寻条件

           DFS(board , row ,col , newx , newy); //继续搜索是否还有联通的
       }
    }

    void solve(vector<vector<char>>& board) 
    {
       int row = board.size();
       int col = board[0].size();

       for(int i = 0 ; i < col ; ++i) //第一行和最后一行找 o
       {
          if(board[0][i] == 'O')
          {
              DFS(board , row ,col , 0 , i) ;
          }

          if(board[row-1][i] == 'O')
          {
              DFS(board , row ,col , row-1 , i) ;
          }
       }

       for(int j = 1 ; j < row ; ++j) //第1列和最后一行列找 o
       {
          if(board[j][0] == 'O')
          {
              DFS(board , row ,col , j , 0) ;
          }

          if(board[j][col-1] == 'O')
          {
              DFS(board , row ,col , j , col-1) ;
          }
       }

       for(int i = 0 ;i < row ; ++i)
       {
           for(int j=0 ; j < col ;++j)
           {
               if(board[i][j] == 'O') //找到被包围的O
               {
                   board[i][j] = 'X';
               }

               if(board[i][j] == 'M')//把边界上与o相连的重新设置
               {
                   board[i][j] = 'O';
               }
           }
       }
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值