图算法总结
2020-05-28 19:01:43
# leetcode
# 总结
# 算法
图的基本概念
基本概念
- 顶点
- 顶点的度
- 边
- 相邻
- 环
- 完全图: 所有顶都相邻
- 二分图: 对于一个图G, V(G)=X∪Y, X∩Y=∅, X中, Y 中任两顶不相邻
- 路径
- 圈
图的表示方式
两种,紧接矩阵和邻接表,如下。
邻接矩阵
邻接表
图的相关问题
其实对于很多非图的问题,也是可以把其看做图的,使用图遍历的方式其进行遍历。例如 LeetCode 138. Copy List with Random Pointer,以图遍历的方式遍历链表;又或者是jump game III,将数组用图遍历的方式展现出来。
图的搜索
BFS
用Queue来遍历吧,先写个样例,以邻接表为例:
1 | /** |
DFS
一般情况下是递归调用DFS较多。而且需要注意的是!!!
Attention: DFS遍历时也要注意preorder还是postorder遍历(有向图的情况下要注意),前者是先遍历当前节点,再去遍历neighbor;后者是先遍历neighbor,再遍历自身。为什么无向图不需要考虑postorder的可能呢?因为无向图都是双向的,如果一个无向图存在环,那么postorder就会引起无限循环,所以对于无向图,都是preorder。
那么对于有向图的postorder遍历有什么区别呢?如果都是在遍历完neighbor以后才将其置为visited的话,那么一旦存在一个有向环,就会无限循环的,和postorder一个道理,跟无向图没有postorder遍历一个道理。因此,我们就需要设置三种状态,unvisited,visiting和visited,当遇到unvisited的时候,我们继续DFS;发现visiting节点,则说明存在环;发现visited节点,则返回,因为已经遍历过了。
下面遍历方式都是对于无向图,有向图的遍历参考:LeetCode 207,最经典的就是拓扑排序。
1 | /** |
二分图
二分图的问题本质上是相当于染色问题,有点像红黑树的感觉。如果能够顺利将整个图染成2种不同颜色,则是二分图,否则不是。实现可以用BFS或DFS均可,下面是三个例题链接。
- LeetCode-785-Is-Graph-Bipartite
- LeetCode 886. Possible Bipartition
- LeetCode-1042-Flower-Planting-With-No-Adjacent