题目描述
把被 X 包围的 O 变成 X;连到边界的 O 保留。
board = 边界 O 不翻转
输出 = 内部 O 被改成 X
思路解析
关键不是背模板,而是看懂为什么这题适合网格 DFS。
1. 先扫描四条边:先扫描四条边
2. 边界上的 O 一定不能翻:边界上的 O 一定不能翻
3. 从边界 O 开始 DFS 标记为安全 S:从边界 O 开始 DFS 标记为安全 S
4. 和边界连通的 O 都标成 S:和边界连通的 O 都标成 S
5. 内部没被标记的 O 才是被包围区域:内部没被标记的 O 才是被包围区域
6. 第二遍把内部 O 改成 X:第二遍把内部 O 改成 X
7. 把 S 恢复成 O:把 S 恢复成 O
8. 完成原地修改:完成原地修改
把这句话记住,下次遇到同类题,就能更快选出方向。
用一个小问题检查自己是不是真的懂了。
参考代码(Python)
Python
1class Solution:
2 def solve(self, board):
3 m, n = len(board), len(board[0])
4 def dfs(r, c):
5 if r < 0 or r >= m or c < 0 or c >= n or board[r][c] != class="cl-str">'O':
6 return
7 board[r][c] = class="cl-str">'S'
8 dfs(r+1,c); dfs(r-1,c); dfs(r,c+1); dfs(r,c-1)
9 for r in range(m):
10 dfs(r, 0); dfs(r, n-1)
11 for c in range(n):
12 dfs(0, c); dfs(m-1, c)
13 for r in range(m):
14 for c in range(n):
15 board[r][c] = class="cl-str">'O' if board[r][c] == class="cl-str">'S' else class="cl-str">'X'复杂度分析
- 时间复杂度:O(mn) —— 每个核心状态按算法要求处理固定次数
- 空间复杂度:O(mn) —— 只保存必要的辅助结构或递归栈
套路模板
模板不是死背,而是提醒你写代码前先把状态、转移和边界排好。
Python
1# 网格 DFS 通用检查表
2# 1. 定义状态/指针/容器
3# 2. 每轮只做一个清晰动作
4# 3. 更新答案并处理边界易错点
- 错误写法:从内部 O 开始判断是否被包围 → 正确写法:从边界 O 反向标记安全区(反向做更简单)
- 错误写法:只按样例推代码 → 正确写法:先写清状态含义和边界条件(样例太少,隐藏用例专打边界)
- 错误写法:变量名和动画不一致 → 正确写法:代码变量沿用动画里的核心名字(学习时最怕脑内维护两套概念)
以上文字与上方动画完全同一思路:先看动画建立直觉 → 读文字巩固 → 关掉页面自己默写一遍代码,能写出来才算真的掌握。