图论07-被包围的区域(Java)

7.被包围的区域

  • 题目描述

给你一个 m x n 的矩阵 board ,由若干字符 'X''O' ,找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O''X' 填充。

示例 1:

java 复制代码
输入: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' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是"相连"的。
  • 题目分析
java 复制代码
--题目分析:
解决被'X'包围的'O'区域的问题,通过将与边界相连的'O'标记为'A',最后再将所有'O'修改为'X',所有'A'修改为'O'来达到目的。下

--思路分析
1.为了找到临海点,我们从四条边分别进行dfs搜索,
如果找到与海相邻的点"O"或者与海相邻的点"O"相邻的"O"点我们将其标记为"A",表示此点不变为"X"

2.通过四个边的dfs,我们已经将所以临海点均标记,此时重新遍历board数组,
将此时数组中的"O"(被包裹点)变为"X",再将"A"还原为"O"即可
  • 代码详解
java 复制代码
1.首先检查输入的二维字符数组 board 是否为空或长度为 0,如果是,则直接返回,不进行任何操作。确定二维字符数组的行数 rows 和列数 cols。
    
2.接下来,遍历第一列和最后一列,以及第一行和最后一行,针对边界上的 'O' 进行深度优先搜索。

3.在 dfs(char[][] board, int i, int j) 方法中,实现深度优先搜索:
首先,检查当前位置是否超出边界或者不是 'O',如果是,则直接返回。
将当前位置标记为 'A',表示未被包围的区域。
继续向当前位置的四个方向进行递归深度优先搜索:向下、向上、向右、向左。

4.完成所有深度优先搜索后,遍历整个二维数组:
将标记为 'O' 的位置改为 'X',表示被包围的区域。
将标记为 'A' 的位置改回 'O',表示未被包围的区域。
  • Java代码实现
java 复制代码
     public void solve(char[][] board) {
        if (board == null || board.length == 0) {
            return;
        }

        int rows = board.length;
        int cols = board[0].length;

        // 遍历第一列和最后一列
        for (int i = 0; i < rows; i++) {
            dfs(board, i, 0);         // 从边界'O'开始深度优先搜索
            dfs(board, i, cols - 1);  // 从边界'O'开始深度优先搜索
        }

        // 遍历第一行和最后一行
        for (int j = 0; j < cols; j++) {
            dfs(board, 0, j);         // 从边界'O'开始深度优先搜索
            dfs(board, rows - 1, j);  // 从边界'O'开始深度优先搜索
        }

        // 恢复标记后的区域
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                if (board[i][j] == 'O') {
                    board[i][j] = 'X';  // 被包围的区域
                } else if (board[i][j] == 'A') {
                    board[i][j] = 'O';  // 未被包围的区域
                }
            }
        }
    }

    // 深度优先搜索函数
    private void dfs(char[][] board, int i, int j) {
        // 边界条件和终止条件
        if (i < 0 || j < 0 || i >= board.length || j >= board[0].length || board[i][j] != 'O') {
            return;
        }

        // 标记当前位置为'A'
        board[i][j] = 'A';

        // 继续向四个方向进行深度优先搜索
        dfs(board, i + 1, j);  // 向下搜索
        dfs(board, i - 1, j);  // 向上搜索
        dfs(board, i, j + 1);  // 向右搜索
        dfs(board, i, j - 1);  // 向左搜索
    }
相关推荐
.Hypocritical.15 分钟前
数据结构笔记——链表成环/反转 + 有序二叉树(BST)构建、遍历、删除
java·数据结构
只会写代码25 分钟前
一套开箱即用实体反射Lambda链式工具,彻底告别原生反射样板代码
java·程序员·源码
AI人工智能+电脑小能手26 分钟前
【大白话说Java面试题 第151题】【06_Spring篇】第11题:说一下 Spring Bean 的生命周期?
java·开发语言·后端·spring·面试
骑士雄师32 分钟前
java面试题:jvm ,mybatis
java·jvm·mybatis
广州浮点FLOATLIC39 分钟前
Creo 许可证利用率怎么优化:制造企业该先看共享规则,还是先看模块占用结构
java·开发语言
2601_962440841 小时前
计算机毕业设计之jsp教室管理系统
java·开发语言·笔记·分布式·算法·课程设计·推荐算法
带刺的坐椅2 小时前
用 ChatModel 构建 LLM 驱动的 Java 应用
java·ai·llm·solon·rag·chatmodel
用户3721574261354 小时前
Java 将 Word 文档转换为 Markdown:基础转换与导出选项详解
java
行者全栈架构师4 小时前
PolarDB + Spring Boot 实战:从自建MySQL到云原生数据库的零停机迁移
java·后端·架构
karry_k20 小时前
MyBatis批量insert-select踩坑:useGeneratedKeys=true 可能让PostgreSQL返回大量插入结果
java·后端