1. 题目解析与核心思路拆解
LeetCode 130题"被围绕的区域"是一道经典的图论连通性问题,考察对矩阵遍历和边界条件的处理能力。题目要求我们将一个由'X'和'O'组成的矩阵中,所有被'X'完全包围的'O'区域替换为'X',而与边缘相连的'O'区域则保持不变。
1.1 题目关键点分析
理解这道题需要抓住几个核心要点:
- 边界定义:矩阵的四条边(第一行、最后一行、第一列、最后一列)上的'O'及其连通区域都不算被包围
- 连通规则:两个'O'只有在水平或垂直方向相邻时才视为连通(对角线不算)
- 原地修改:题目要求直接修改输入矩阵,而不是返回新矩阵
- 包围判定:一个'O'区域要被视为被包围,必须满足该区域中没有任何一个'O'位于矩阵边缘
注意:很多初学者容易忽略"与边缘连通"这个条件,试图直接判断每个'O'是否被'X'包围,这种思路会导致逻辑复杂且效率低下。
1.2 解题思路对比
这道题有两种主流解法,各有特点:
正向判断法(解法一):
- 遍历矩阵中的每个'O'
- 使用BFS/DFS找出其连通区域
- 判断该区域是否接触边缘
- 根据判断结果决定是否替换为'X'
反向标记法(解法二):
- 先找出所有与边缘连通的'O'区域并标记
- 然后遍历整个矩阵
- 将未被标记的'O'改为'X'
- 将被标记的'O'恢复为原始值
从效率角度看,解法二通常更优,因为它只需要处理边缘相关的'O',避免了不必要的连通区域判断。下面我们将深入分析这两种实现方式。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. BFS正向解法详解
2.1 算法流程拆解
BFS解法的核心流程可以分为以下几个步骤:
- 矩阵遍历:逐个检查矩阵中的每个单元格
- 发现'O':当遇到'O'时,初始化BFS遍历
- 连通区域探索:
- 使用队列实现BFS
- 记录当前连通区域的所有坐标
- 检查是否触及边缘
- 结果处理:
- 如果区域被包围,全部改为'X'
- 否则恢复为'O'
typescript复制function solve(board: string[][]): void {
if (board.length === 0 || board[0].length === 0) return;
const rows = board.length;
const cols = board[0].length;
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
if (board[i][j] === 'O') {
const queue: [number, number][] = [];
const tempQueue: [number, number][] = [];
let isSurrounded = true;
tempQueue.push([i, j]);
board[i][j] = 'A'; // 临时标记
