Same as Course Schedule (207) but instead of returning a boolean, return the ordering in which courses should be taken. If impossible (cycle), return an empty array.
1 ≤ numCourses ≤ 20000 ≤ prerequisites.length ≤ 5000order list fills in exactly the sequence you'd assign to the team. If you hit a deadlock (cycle), no valid schedule exists.Replace completed += 1 with order.append(cur). The algorithm is identical — you just collect the processing sequence instead of counting it. Return order if len(order) == numCourses, else [].
Node label = course · small label = position in order (#N) or remaining in-degree
def findOrder(self, numCourses, prerequisites):
adj = [[] for _ in range(numCourses)]
for a, b in prerequisites:
adj[b].append(a)
# 0 = unvisited, 1 = in path, 2 = done
state = [0] * numCourses
order = []
def dfs(node):
if state[node] == 1: return False # cycle
if state[node] == 2: return True
state[node] = 1
for nei in adj[node]:
if not dfs(nei): return False
state[node] = 2
order.append(node) # post-order = reverse topo
return True
for i in range(numCourses):
if not dfs(i): return []
return order[::-1] # reverse post-orderWhen two courses both have in-degree 0 at the same time, either can go first. Kahn's BFS produces one valid topological order — any valid order is accepted.
DFS explores deep first, appending a node only after all its dependents are processed. This gives reverse-topological order — you must reverse the list at the end. BFS naturally gives the correct forward order.
Discussion
…