算法日常・每日刷题--<BFS>4

130. 被围绕的区域 - 力扣(LeetCode)130. 被围绕的区域 - 给你一个 m x n 的矩阵 board ,由若干字符 'X' 和 'O' 组成,捕获 所有 被围绕的区域: * 连接:一个单元格与水平或垂直方向上相邻的单元格连接。 * 区域:连接所有 'O' 的单元格来形成一个区域。 * 围绕:如果一个区域中的所有 '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']解释:https://pic.leetcode.cn/1718167191-XNjUTG-image.png在上图中,底部的区域没有被捕获,因为它在 board 的边缘并且不能被围绕。示例 2:输入:board = \['X']输出:\['X'] 提示: * m == board.length * n == boardi.length * 1 <= m, n <= 200 * boardij 为 'X' 或 'O'https://leetcode.cn/problems/surrounded-regions/description/

题目描述

给一个 m × n 的矩阵,矩阵由字符 'X''O' 组成,捕获所有被围绕的区域。

  • 连接:单元格上下左右相邻算作连接。
  • 区域 :全部相连的O构成一块区域。
  • 被包围 :如果一块区域所有O都不在矩阵边界,就代表被X完全包围,需要把这部分O原地修改成X

边界上的O一定不会被包围,和边界O连通的内部O同样不会被包围,只有完全被 X 围在里面的 O 才要替换。

注意:直接原地修改数组,不需要返回值。


做题思路

直接找被包围的O不好处理,我们逆向思考:

  1. 边界上的 O 一定不会被包围,所有和边界 O 连通的 O,也一定不会被包围。
  2. 遍历矩阵四条边界,遇到O就做 BFS,把连通的O临时标记成.(做记号,表示这部分是安全的,不能被修改)。
  3. 遍历整个矩阵做还原:
    • 仍然是O:说明没有和边界连通,是被包围的,改成X
    • .:原本是边界连通的 O,恢复回O

核心:不找被包围的,先找不会被包围的,标记之后再批量修改。

cpp 复制代码
class Solution {
public:
int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    int m,n;
    void solve(vector<vector<char>>& board) {
        m=board.size();
        n=board[0].size();
        for(int j=0;j<n;j++)
        {
            if(board[0][j]=='O')
            bfs(board,0,j);
            if(board[m-1][j]=='O')
            bfs(board,m-1,j);
        }
        for(int i=0;i<m;i++)
        {
            if(board[i][0]=='O')
            bfs(board,i,0);
            if(board[i][n-1]=='O')
            bfs(board,i,n-1);
        }

        //还原
        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';
            }
        }
    }
    
    void bfs(vector<vector<char>>& board,int i,int j)
    {
        queue<pair<int ,int>>q;
        q.push({i,j});
       board[i][j]='.';
           
 
        while(q.size())
        {
            auto [a,b]=q.front();
            q.pop();
            for(int k=0;k<4;k++)
            {
                int x=a+dx[k];
                int y=b+dy[k];
                if(x>=0 && x<m && y>=0 && y<n && board[x][y]=='O')
                {
                    q.push({x,y});
                    board[x][y]='.';
                   
                }
            }
        }
        
    }
};
相关推荐
额额额对了11 小时前
数据结构:二叉树
c语言·数据结构·算法
iNeuOS工业互联网11 小时前
iNeuOS_Vision_视觉分析,增加SAM3模型对实例分割和目标检测AI自动标注图片样本功能
人工智能·算法·目标检测
qeen8712 小时前
【数据结构】红黑树的算法原理解析与实现
开发语言·数据结构·c++·算法·红黑树
码匠许师傅12 小时前
【C++ 面试真题】20. 聊聊 C++ 的标准库常用算法
c++·算法·面试
m0_5474866613 小时前
《数据结构与算法(Python语言版)》全套PPT课件2026
数据结构·算法
个 人 练 习 生13 小时前
数据结构入门:算法复杂度
开发语言·数据结构·经验分享·学习·程序人生·算法
Ricardo-Yang13 小时前
无人机单目深度估计测试:ZipDepth 与 AerialMetric
人工智能·算法·机器学习·计算机视觉·无人机
Nil20813 小时前
golang解决单词转换
算法
imaol114 小时前
文件编程--标准IO
linux·运维·算法
青 春 记 忆14 小时前
LeetCode 121. 买卖股票的最佳时机|Python 解法详解
python·算法·leetcode