拓扑排序之 leetcode 207.课程表
原题:207. 课程表 - 力扣(LeetCode)
这是一道经典的拓扑排序题目,为理解和解决这类题目,我们首先了解下拓扑排序。
在图论中,拓扑排序(Topological Sorting)是一个有向无环图(DAG, Directed Acyclic Graph)的所有顶点的线性序列,它有以下性质
(1)唯一性
当有向无环图呈线性结构(即从第一个节点到最后一个节点有一条路径连接所有节点)时,拓扑排序唯一。当图中存在多个无依赖关系的节点时,拓扑排序不唯一。
(2)时间复杂度
Kahn算法和DFS算法的时间复杂度均为O(V+E),其中V是节点数,E是边数。两种算法都能高效处理大规模图结构。
(3)环检测(这个是解题的关键)
如果算法结束后拓扑排序的节点数少于图中总节点数,说明图中存在环。这使得拓扑排序算法同时成为检测有向图是否有环的有效方法。
其他背景:
什么是度?出度?入度?
https://zh.wikipedia.org/wiki/%E5%BA%A6_(%E5%9B%BE%E8%AE%BA)
解法:
这里主要分为两种,第一种是BFS广度优先搜索(基于入度的Kahn算法),第二种是DFS深度优先搜索。
(1)BFS
func canFinish(numCourses int, pre [][]int) bool {edges := make(map[int][]int,numCourses)indges := make([]int,numCourses)for i := range pre {p:=pre[i]edges[p[1]] = append(edges[p[1]],p[0])indges[p[0]]++}q:=[]int{}for i := range indges {if indges[i]== 0 {q = append(q,i)} }result := []int{}for len(q)>0 {u := q[0]q=q[1:]result = append(result,u)for _,v:=range edges[u] {indges[v]--if indges[v] == 0 {q = append(q,v)}} }return len(result) == numCourses}