【LeetCode 面试经典150题】130. Surrounded Regions 被围绕的区域

130. Surrounded Regions(被围绕的区域)

题目大意

Given an m x n matrix board containing ‘X’ and ‘O’, capture all regions that are 4-directionally surrounded by ‘X’.

A region is captured by flipping all 'O’s into 'X’s in that surrounded region.

中文释义

给定一个 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’ 不应该被翻转如果它:
      • 在边界上,或者
      • 它相邻于不应该被翻转的 ‘O’。
        底部的 ‘O’ 在边界上,所以它没有被翻转。
        其他三个 ‘O’ 形成了一个被围绕的区域,所以它们被翻转了。
  • 示例 2:

    • 输入:board = [["X"]]
    • 输出:[["X"]]

限制条件

  • m == board.length
  • n == board[i].length
  • 1 <= m, n <= 200
  • board[i][j] 是 ‘X’ 或 ‘O’。

解题思路

使用深度优先搜索(DFS)来解决问题。首先处理边界上的 ‘O’,防止它们被错误地翻转,然后处理内部区域的 ‘O’。

步骤说明

  1. 初始化一个标记节点是否已访问的二维布尔数组 visited
  2. 对矩阵的左右边界进行 DFS,标记不应该翻转的 ‘O’。
  3. 对矩阵的上下边界进行 DFS,标记不应该翻转的 ‘O’。
  4. 对矩阵内部的每个节点进行 DFS:
    • 如果节点是 ‘O’ 且未被标记为不翻转,则翻转它。
  5. 返回翻转后的矩阵。

代码

class Solution {
public:
    void dfs(int i, int j, vector<vector<char>>& board, vector<vector<bool>>& visited, bool flag) {
        if (i < 0 || i >= board.size() || j < 0 || j >= board[i].size()) return;
        if (board[i][j] == 'X' || visited[i][j]) return;

        visited[i][j] = true;
        if (flag) {
            board[i][j] = 'X';
        }
        dfs(i - 1, j, board, visited, flag);
        dfs(i + 1, j, board, visited, flag);
        dfs(i, j + 1, board, visited, flag);
        dfs(i, j - 1, board, visited, flag);
    }

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

        for (int i = 0; i < n; i++) {
            dfs(i, 0, board, visited, false);
            dfs(i, m - 1, board, visited, false);
        }
        for (int j = 0; j < m; j++) {
            dfs(0, j, board, visited, false);
            dfs(n - 1, j, board, visited, false);
        }
        for (int i = 1; i < n - 1; i++) {
            for (int j = 1; j < m - 1; j++) {
                dfs(i, j, board, visited, true);
            }
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值