❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容,和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣!
推荐:数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注
导航:
- LeetCode解锁1000题: 打怪升级之旅:每题都包括3-5种算法,以及详细的代码实现,刷题面试跳槽必备
- 漫画版算法详解:通过漫画的形式和动态GIF图片把复杂的算法每一步进行详细可视解读,看一遍就掌握
- python源码解读:解读python的源代码与调用关系,快速提升代码质量
- python数据分析可视化:企业实战案例:企业级数据分析案例与可视化,提升数据分析思维和可视化能力
- 程序员必备的数学知识与应用:全面详细的介绍了工程师都必备的数学知识
期待与您一起探索技术、持续学习、一步步打怪升级 欢迎订阅本专栏❤️❤️
解读力扣第 130 题:被围绕的区域
在本篇文章中,我们将详细解读力扣第 130 题“被围绕的区域”。通过学习本篇文章,读者将掌握如何使用深度优先搜索(DFS)或广度优先搜索(BFS)来解决二维网格问题的技巧。
问题描述
力扣第 130 题“被围绕的区域”描述如下:
给你一个
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"]]
示例 2:
输入: board = [["X"]]
输出: [["X"]]
解题思路
初步分析:
- 我们需要找到所有被
'X'
围绕的'O'
区域,并将这些'O'
替换为'X'
。 - 如果一个
'O'
位于边界上或连接到边界上的'O'
,则不能被替换。
- 我们需要找到所有被
DFS/BFS方法:
- 我们可以使用深度优先搜索(DFS)或广度优先搜索(BFS)来标记从边界上开始的
'O'
,这些'O'
不能被替换。 - 然后遍历整个网格,将未标记的
'O'
替换为'X'
,标记的'O'
恢复原状。
- 我们可以使用深度优先搜索(DFS)或广度优先搜索(BFS)来标记从边界上开始的
代码实现
解法一:深度优先搜索(DFS)方法
步骤:
- 从网格的四个边界开始,进行DFS,将连接到边界的
'O'
标记为临时字符'T'
。 - 遍历整个网格,将未被标记的
'O'
替换为'X'
,将标记的'T'
恢复为'O'
。
- 从网格的四个边界开始,进行DFS,将连接到边界的
伪代码:
def dfs(board, i, j): if i < 0 or i >= m or j < 0 or j >= n or board[i][j] != 'O': return board[i][j] = 'T' dfs(board, i + 1, j) dfs(board, i - 1, j) dfs(board, i, j + 1) dfs(board, i, j - 1)
代码实现
def solve(board):
if not board or not board[0]:
return
m, n = len(board), len(board[0])
def dfs(i, j):
if i < 0 or i >= m or j < 0 or j >= n or board[i][j] != 'O':
return
board[i][j] = 'T'
dfs(i + 1, j)
dfs(i - 1, j)
dfs(i, j + 1)
dfs(i, j - 1)
# 从边界开始DFS,将所有连接的'O'标记为'T'
for i in range(m):
dfs(i, 0)
dfs(i, n - 1)
for j in range(n):
dfs(0, j)
dfs(m - 1, j)
# 遍历整个网格,将未被标记的'O'替换为'X',将标记的'T'恢复为'O'
for i in range(m):
for j in range(n):
if board[i][j] == 'O':
board[i][j] = 'X'
elif board[i][j] == 'T':
board[i][j] = 'O'
# 测试案例
board1 = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]
solve(board1)
print(board1) # [["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]
board2 = [["X"]]
solve(board2)
print(board2) # [["X"]]
复杂度分析
- 时间复杂度:O(m * n),其中 m 是网格的行数,n 是网格的列数。每个点最多被访问两次。
- 空间复杂度:O(m * n),递归调用栈的最大深度。
代码优化
解法二:广度优先搜索(BFS)方法
步骤:
- 使用队列从边界开始进行广度优先搜索(BFS),将连接到边界的
'O'
标记为临时字符'T'
。 - 遍历整个网格,将未被标记的
'O'
替换为'X'
,将标记的'T'
恢复为'O'
。
- 使用队列从边界开始进行广度优先搜索(BFS),将连接到边界的
伪代码:
def bfs(board, i, j): queue.append((i, j)) while queue: x, y = queue.pop(0) if x < 0 or x >= m or y < 0 or y >= n or board[x][y] != 'O': continue board[x][y] = 'T' queue.append((x + 1, y)) queue.append((x - 1, y)) queue.append((x, y + 1)) queue.append((x, y - 1))
代码实现
from collections import deque
def solve(board):
if not board or not board[0]:
return
m, n = len(board), len(board[0])
def bfs(i, j):
queue = deque([(i, j)])
while queue:
x, y = queue.popleft()
if x < 0 or x >= m or y < 0 or y >= n or board[x][y] != 'O':
continue
board[x][y] = 'T'
queue.append((x + 1, y))
queue.append((x - 1, y))
queue.append((x, y + 1))
queue.append((x, y - 1))
# 从边界开始BFS,将所有连接的'O'标记为'T'
for i in range(m):
bfs(i, 0)
bfs(i, n - 1)
for j in range(n):
bfs(0, j)
bfs(m - 1, j)
# 遍历整个网格,将未被标记的'O'替换为'X',将标记的'T'恢复为'O'
for i in range(m):
for j in range(n):
if board[i][j] == 'O':
board[i][j] = 'X'
elif board[i][j] == 'T':
board[i][j] = 'O'
# 测试案例
board1 = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]
solve(board1)
print(board1) # [["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]
board2 = [["X"]]
solve(board2)
print(board2) # [["X"]]
复杂度分析
- 时间复杂度:O(m * n),其中 m 是网格的行数,n 是网格的列数。每个点最多被访问两次。
- 空间复杂度:O(min(m, n)),用于队列存储的空间。
总结
本文详细解读了力扣第 130 题“被围绕的区域”,通过深度优先搜索(DFS)和广度优先搜索(BFS)两种不同的解法,帮助读者深入理解二维网格问题的解决思路。希望读者通过本文的学习,能够在力扣刷题的过程中更加得心应手。
参考资料
- 《算法导论》—— Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein
- 力扣官方题解
🌹🌹如果觉得这篇文对你有帮助的话,记得一键三连关注、赞👍🏻、收藏是对作者最大的鼓励,非常感谢 ❥(^_-)
❤️❤️作者知识有限,如有错误,请各位大佬评论区批评指正,不胜感激❥(^_-)