遍历:BFS
BFS每次搜索的时候从所有的frontier开始扩展,并保留新的起点在frontier。BFS可以用从一点(或者多源)开始寻找最近的答案,或者无权有向图或者无向两点之间的最短距离。
DFS与BFS的比较:
在有一些问题中,BFS会比DFS更加高效。例如在社交网络想要寻找两个朋友的链接度,DFS可能会钻进死胡同去搜索另一个朋友所有的subtree再回头过来找与他们更亲近的朋友。
在分布式算法中,BFS作为“多兵作战“的算法比DFS的“单打独斗“更合适。比如说在crawl网页的过程中,我们可以暂时把目前爬到的域名frontier存在硬盘或者缓存中,然后让多个线程从frontier中选取一个域名继续爬。
回看前面DFS里的迷宫题,我们用BFS可以这样求解。
queue = [enter]
paths = {enter: [enter]}
while queue:
v = queue.pop(0)
if v==exit: return path[v]
for u in neighbors(p):
if u in path: continue
if wall(u, v): continue
queue.append(u)
paths[u] = paths[v] + [u]
return []这里我们简单起见只返回了任一可行解。留意这里因为要记录最后可行解的路径,我们用paths: point -> path来保存在任一点到达这一点的路径,并代替了使用vis数组来判断是否已经访问了某一点。
例题:打开转盘锁
你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有10个数字: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' 。每个拨轮可以自由旋转:例如把 '9' 变为 '0','0' 变为 '9' 。每次旋转都只能旋转一个拨轮的一位数字。
锁的初始数字为 '0000' ,一个代表四个拨轮的数字的字符串。
列表 deadends 包含了一组死亡数字,一旦拨轮的数字和列表里的任何一个元素相同,这个锁将会被永久锁定,无法再被旋转。
字符串 target 代表可以解锁的数字,你需要给出解锁需要的最小旋转次数,如果无论如何不能解锁,返回 -1 。
示例 1:
节省空间的双源BFS
例题:离建筑物最近的距离
例题:撞球迷宫
和一般的迷宫不一样,如果我们在Tilt Maze里面从起点找终点,我们就加入状态来表示球的行进方向,而且要多一个状态来表示“静止”。下面BFS和DFS中,用0-3来表示四个方向,用4来表示静止状态。

Last updated
Was this helpful?