BFS应用

BFS使用场景

连通块问题(Connected Component)

  1. 通过一个点找到图中连通的所有点
  2. 非递归的方式找所有方案

分层遍历(Level Order Traversal)

  1. 图的层序遍历
  2. 简单图最短路径(Simple Graph Shortest Path)
  • 简单图
    • 没有方向
    • 没有权重
    • 两点之间最多只有一条边
    • 一个点没有一条边直接连着自己
  • 如果图中存在环,则同一个节点可能重复进入队列
    • 重复BFS没有意义
      • 对于连通块问题,不可能带来新的节点
      • 对于最短路问题,不可能带来最短的路径
    • 使用哈希表去重
      • C++:unordered_map/unordered_set

拓扑排序(Topological Sorting)

  1. 求任意拓扑序
  2. 求是否有拓扑序
  3. 求字典序最小的拓扑序
  4. 求是否唯一拓扑序
拓扑排序不是传统的排序算法
一个图可能存在多个拓扑序(Topological Order),也可能不存在任何拓扑序
1.统计每个点的入度
2.将每个入度为0的点放入队列(Queue)中作为起始点
3.不断从队列中拿出一个点,去掉这个点的所有连边(指向其他点的边),其他点的相应入度-1
4.一旦发现新的入度为0的点,丢回队列中

BFS算法

BFS通用模板

step 1:初始化
把初始节点放到queue里,如果有多个就都放进去
并标记初始节点的距离为0,记录在distance的map里
distance有两个作用,一个是判断是否已经访问过,二是记录离起点的距离
step 2:不断访问队列
while循环+每次pop队列中的一个点出来
	//分层操作
	//int size=queue.size();
	//for(int i=0;i<size;i++)
	step 3:拓扑相邻节点
	pop出的节点的相邻节点,加入队列并在distance中存储距离

137 Clone Graph克隆图

将整个算法分解为三个步骤
1.找到所有点
2.复制所有点
3.复制所有边
一旦入队就要马上访问标记,否则,会有元素重复入列

120 Word Ladder单词接龙

step1:构造dict,必须加入end,可以加入start
step2:记录最短路线长度,起始长度为1
	到下一层(不是当前层)的长度
	当前层有size个元素
		step3:得到下一步的单词
			如果下一层的词为尾词,直接返回当前到下一层(不是当前层)的长度
			加入下一层,为后面BFS做准备
	不能实现首尾接龙,返回0
step3:得到下一步的单词
	枚举当前替换字母
		枚举替换位置
			step4:返回替换后的字符串
			如果字母替换后的的单词存在于dict,加入nextWords
step4:返回替换后的字符串
	在s中,把位置index的字母替换成c,返回替换后的字符串

433 Number of Islands

矩阵坐标变换数组
deltaX,deltaY
是否在界内:isInBound/isValid
1.逐行逐列进行遍历
2.如果找到一个1,岛屿数量增1
3.把所有跟这个1相连的1都找出来,所有这些相连的1代表一个岛
4.回到步骤1继续遍历

需要定义一个class,表示坐标系中的一个点
定义四个方向的偏移量
特殊情况处理
记录某点是否被BFS过(如果之前BFS过,不应再次被BTS)
遍历矩阵中的每一个点
	如果为海洋,无需BFS
	如果该点已经被BFS,无需做冗余遍历,重复计算

611 Knight Shortest Path

矩阵坐标变换数组
deltaX,deltaY
是否在界内:isInBound/isValid
8个方向的偏移量
遍历8个不同的方向
	新坐标点
	如果之前已经到达过词典,不可能通过再次BFS找到最短路径,还会造成死循环
不能到达,返回-1

如果一个点越界或者为障碍物,返回falsse,否则true1表示障碍物,返回false

616 Course Schedule II(问是否存在拓扑排序)

+有依赖关系+有向+无环=>拓扑排序
构建图,代表(先修课->多个后修课)的映射
图的初始化,每个先修课->空后修课
1.统计每个点的入度,并构造图
2.将每个入度为0的点进入队列中作为起始点
记录已修课程的数量
记录拓扑顺序
3.不断从队列中拿出一个点,去掉这个点的所有连边(指向其他点的边),其他点的相应入度-1
	当前点的邻居的入度减1,表示每个后修课的一门先修课已经完成
	4.一旦发现新的入度为0的点,丢回队列中
	表示一门后修课的所有先修课已经完成,可以被修了

127 Topological Sorting 拓扑排序(求任意一个拓扑排序)

同上

605 Sequence Reconstruction(问拓扑排序是否唯一)

queue的长度>1,说明结果不唯一

892 Ailen Dictionary 外星人字典(求字典序最小的拓扑排序)

如果数据不合理,graph为空,返回空字符串
合理则进行拓扑排序

合理判断:
存放(字母->右面的多个字母)的映射关系
生成所有的点,每个点的后缀点暂时为空
生成所有的边,找到一个点之后的点,并建立连接
	如果输入["abc","ab"]"abc"出现在"ab"前面,不合法,返回NULL

拓扑排序:
1.统计每个点的入度
2.将每个入度为0的点放入队列中作为起始节点
要求:这里可能有多个有效的字母顺序,返回以正常字典顺序看来最小的
所以这里要heapify,从所有可以出队的元素中,先出对字典比较小的元素
记录拓扑顺序(外星人字典排序)
3.不断从队列中拿出一个点,去掉这个点的所有连边(指向其他点的边)
其他点的相应的入度-1
	当前点的邻居的入度减1
	4.一旦发现新的入度为0的点,丢回队列中

统计每个点的入度:
统计每个点的入度,如果一个点的入度为0,那么这个点依然存在于dict中,对应入度为0
	初始化所有点的入度为0
		所有邻居的入度加1

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值