[LeetCode]210 课程表II

题目描述

现在你总共有 n 门课需要选,记为 0 到 n-1。

在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]

给定课程总量以及它们的先决条件,返回你为了学完所有课程所安排的学习顺序。

可能会有多个正确的顺序,你只要返回一种就可以了。如果不可能完成所有课程,返回一个空数组。

示例1:

输入: 2, [[1,0]] 
输出: [0,1]
解释: 总共有 2 门课程。要学习课程 1,你需要先完成课程 0。因此,正确的课程顺序为 [0,1] 。

示例2:

输入: 4, [[1,0],[2,0],[3,1],[3,2]]
输出: [0,1,2,3] or [0,2,1,3]
解释: 总共有 4 门课程。要学习课程 3,你应该先完成课程 1 和课程 2。并且课程 1 和课程 2 都应该排在课程 0 之后。
     因此,一个正确的课程顺序是 [0,1,2,3] 。另一个正确的排序是 [0,2,1,3] 。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class Solution:
def findOrder(self, numCourses, prerequisites):
"""
:type numCourses: int
:type prerequisites: List[List[int]]
:rtype: List[int]
"""
graph = self.get_graph(numCourses, prerequisites)
inorder = self.get_inorder(graph)

queue = [node for node in inorder if inorder[node] == 0]
result = []

while queue:
node = queue.pop(0)
result.append(node)
neighbors = graph[node]
for neighbor in neighbors:
inorder[neighbor] -= 1
if inorder[neighbor] == 0:
queue.append(neighbor)

for inorder_val in inorder.values():
if inorder_val != 0:
return []

return result

def get_graph(self, num, edges):
graph = {i: list() for i in range(num)}

for dst, src in edges:
graph[src].append(dst)

return graph

def get_inorder(self, graph):
inorder = {i: 0 for i in graph.keys()}

for node, neighbors in graph.items():
for neighbor in neighbors:
inorder[neighbor] += 1

return inorder