# 第75期-基础算法:广度优先搜索 被围绕的区域
Python是一门需要不断实践练习的编程语言,本文档将AI大学堂学员交流群的Python每周练习进行汇总,希望各位小伙伴能够多进行实践练习,逐渐爱上这门神奇的编程语言,掌握它并在生活中能够使用它。
# 1 问题描述
被围绕的区域 给你一个 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' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
示例 2:
输入: board = [["X"]]
输出: [["X"]]
示例 3:
输入: board = [['O', 'O'], ['O', 'O']]
输出: [['O', 'O'], ['O', 'O']]
初始代码
from typing import List
class Solution:
def solve(self, board: List[List[str]]) -> None:
#在此之间填写代码
print(Solution().solve([["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]))
print(Solution().solve([["X"]]))
print(Solution().solve([["O","O"],["O","O"]]))
2
3
4
5
6
7
8
# 2 解题思路
- 标签:广度优先搜索 / 深度优先搜索
- 从边界出发吧,先把边界上和 O 连通点找到, 把这些变成 B
- 然后遍历整个 board 把 O 变成 X, 把 B 变成 O
- 如下图所示:
# 3 解题方法
from typing import List
class Solution:
def solve(self, board: List[List[str]]) -> None:
a,b=len(board),len(board[0])
queue=[]
i,x=0,0
while i < a:
if board[i][x]=='O':queue.append((i,x))
i+=1
if i==a and x!=b-1:
i=0
x=b-1
i,x=0,0
while i < b:
if board[x][i]=='O':queue.append((x,i))
i+=1
if i==b and x!=a-1:
i=0
x=a-1
while queue:
cur=queue.pop(0)
for i in ((1,0),(0,1),(-1,0),(0,-1)):
x,y=cur[0]+i[0],cur[1]+i[1]
if 0<=x<a and 0<=y<b and board[x][y]=='O':
queue.append((x,y))
board[cur[0]][cur[1]]='B'
for i in range(a):
for j in range(b):
if board[i][j]=='O':board[i][j]='X'
if board[i][j]=='B':board[i][j]='O'
return board
print(Solution().solve([["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]))
print(Solution().solve([["X"]]))
print(Solution().solve([["O","O"],["O","O"]]))
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
第1-3,35-37行: 题目中已经给出的信息,运行代码时要根据这些代码进行编辑
第4行: 定义变量a,b用于存放矩阵的长度和宽度
第5行: 定义列表queue用于存放接下来需要遍历的坐标
第6行: 定义变量i,x用于遍历矩阵边界的点的坐标
第7-19行: 将矩阵边界上所以等于'O'的点放进queue中
第21行: 判断queue列表是否为空,若不为空则还有坐标需要遍历,继续循环
第22行: 定义坐标cur用于存放queue接下来需要使用的第一个坐标并从queue中删除该坐标
第23行: 使用for循环遍历上下左右四个方向
第24行: 定义变量x,y用于存放该方向的横竖坐标
第25行: 判断该点横竖坐标是否在矩阵内且该点是否等于'O'
第26行: 若满足条件,则在queue队列中加如带点坐标,用于之后该点扩散
第14行: 将之前的点变成'B'防止下次循环又加上他
第29-32行: 重新遍历矩阵,将所有的'O'变成'X',将所有的'B'变成'O'
第33行: 返回修改后的矩阵
代码运行结果为:
# 算法讲解
这里用到了基础算法:广度优先搜索,简单讲解下这个算法:
广度优先搜索
广度优先搜索(也称宽度优先搜索,缩写BFS,以下采用广度来描述)是连通图的一种遍历策略。因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较广的区域,故得名。
树的广度优先遍历
图的广度优先遍历
树与图
# 4 视频解析
高清视频讲解,请查看AI大学堂Python基础实战100例 (opens new window)
关注『讯飞AI大学堂』公众号,发送 python100 即可领取Python基础实战100例源代码