210.课程表 II
https://leetcode-cn.com/problems/course-schedule-ii/
一、拓扑排序
https://zh.wikipedia.org/wiki/%E6%8B%93%E6%92%B2%E6%8E%92%E5%BA%8F
维护一个入度为0的队列,每次优先访问队列节点,并将相邻节点符合入度为0的入队,直到对空,若最后队列不能清空说明有环,否则访问的顺序就是拓扑排序
二、dfs实现拓扑
图后续遍历得到访问序列,再将序列逆序得到拓扑排序(如果存在的话)
class Solution:
def findOrder(self, numCourses: int, prerequisites) :
# 构建邻接表
graph = {}
for i in range(numCourses):
graph[i] = list()
for edge in prerequisites:
f = edge[1]
t = edge[0]
graph[f].append(t) # 写入邻接表
visited = [False] * numCourses # 记录访问过的节点
onPath = [False] * numCourses
postOrder = []
self.hasCycle = False
def travel(s):
if onPath[s]:
self.hasCycle = True
if visited[s]: # 访问过则停止
return
visited[s] = True # 标记已访问
onPath[s] = True # 尝试访问该节点
# 访问所有相邻节点
for neigh in graph[s]:
travel(neigh)
#后序遍历
onPath[s] = False # 退出回溯前恢复现场
postOrder.append(s) #记录后序序列
return
# 以每个节点为起始尝试遍历
for i in range(numCourses):
travel(i)
# 若无环则返回后序的逆序
return [] if self.hasCycle else postOrder[::-1]
最后更新于