Note: This is topological sort. Wiki link.
Related Problem: 207. Course Schedule.

DFS on Directed Graph:
var findOrder = function (numCourses, prerequisites) {
const n = numCourses,
adjList = buildGraph(n, prerequisites),
visited = new Array(n).fill(-1),
arrival = new Array(n).fill(-1),
departure = new Array(n).fill(-1),
topSort = []
let timestamp = 0
for (let v = 0; v < n; v++) {
if (visited[v] === -1) {
// if cycle found, you cannot complete the courses
if (dfs(v)) return []
}
}
return topSort.reverse() // no cycle found anywhere
// -----------------------------------------------
function dfs(source) {
arrival[source] = timestamp
timestamp++
visited[source] = 1
for (const neighbor of adjList[source]) {
if (visited[neighbor] === -1) {
if (dfs(neighbor)) return true
} else {
// This is a back edge, hence a cycle
if (departure[neighbor] === -1) return true
}
}
departure[source] = timestamp
timestamp++
topSort.push(source)
return false
}
// -----------------------------------------------
function buildGraph(n, edges) {
const adjList = new Array(n).fill().map(() => [])
for (const [src, dest] of edges) {
adjList[dest].push(src)
}
return adjList
}
}
// tests
console.log(
findOrder(4, [
[1, 0],
[2, 0],
[3, 1],
[3, 2],
])
)
console.log(
findOrder(6, [
[1, 0],
[2, 1],
[3, 1],
[4, 3],
[3, 0],
// [0, 2],
[2, 4],
[3, 5],
[0, 5],
])
)