云计算百科
云计算领域专业知识百科平台

【Classic 150 刷题计划】 LeetCode 130. 被围绕的区域 | C++ 矩阵 DFS 与逆向边界保护法

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"]]


💡 破题思路:逆向思维 (从边缘出发的 DFS 标记)

如果正向去检查每一个内部的 'O' 是不是被包围,需要处理大量的连通性边界,极其复杂。
大厂满分秘籍:逆向思维(保卫边区)
所有能够直接或间接和矩阵边缘的 'O' 连通的 'O',都是绝对不可能被包围的“漏网之鱼”。

算法步骤:

  • 搜寻边缘:遍历矩阵的四条边界(第一行、最后一行、第一列、最后一列)。
  • 深度优先搜索 (DFS):一旦在边界上发现了 'O',立刻以它为起点开始 DFS,把所有和它连通的 'O' 全部打上访问标记(或者原地修改为一个特殊字符,如 'A')。
  • 全局清洗:再次遍历整个矩阵:
    • 被标记过(或修改过)的 'O':说明它们与边缘相连,属于安全区,恢复或保持为 'O'。
    • 没被标记过的 'O':说明它们被密不透风的 'X' 彻底包围,无路可逃,全部无情转化为 'X'。

  • 💻 C++ 代码实现 (原汁原味作者版)

    class Solution {
    public:
    // 方向向量:右、下、左、上
    int dx[4] = {0, 1, 0, –1};
    int dy[4] = {1, 0, –1, 0};

    // ⚠️ 注意:固定大小的 st 数组在矩阵超过 210×210 时会越界
    // 工业级建议直接在原地修改 board 字符(如改成 'A')来省去 st 数组
    int st[210][210];
    int m, n;

    void solve(vector<vector<char>>& board) {
    m = board.size(), n = board[0].size();

    // 1. 扫描四条边界,寻找所有与边缘相连的 'O'
    for (int i = 0; i < m; i ++ )
    for (int j = 0; j < n; j ++ )
    {
    if (board[i][j] == 'O')
    {
    // 如果当前点落在四条边界上,立刻触发 DFS 连通块标记
    if (i == 0 || j == 0 || i == m – 1 || j == n – 1)
    dfs(i, j, board);
    }
    }

    // 2. 全局清剿:根据 st 状态重塑矩阵
    for (int i = 0; i < m; i ++ )
    for (int j = 0; j < n; j ++ )
    {
    if (st[i][j]) board[i][j] = 'O'; // 边缘连通的安全区,保留
    else board[i][j] = 'X'; // 内部被包围的死区,全部杀死
    }
    }

    void dfs(int x, int y, vector<vector<char>>& board)
    {
    st[x][y] = 1; // 标记为安全状态

    for (int i = 0; i < 4; i ++ )
    {
    int xx = x + dx[i], yy = y + dy[i];
    // 越界检查 + 必须是 'O' + 必须未被访问过
    if (xx >= 0 && xx < m && yy >= 0 && yy < n && board[xx][yy] == 'O' && !st[xx][yy])
    {
    dfs(xx, yy, board);
    }
    }
    }
    };

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 【Classic 150 刷题计划】 LeetCode 130. 被围绕的区域 | C++ 矩阵 DFS 与逆向边界保护法
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!