Skip to main content

Course Schedule

Problem

There are a total of numCourses courses you have to take, labeled from 0 to numCourses - 1. You are given an array prerequisites where prerequisites[i] = [ai, bi] indicates that you must take course bi first if you want to take course ai.

  • For example, the pair [0, 1], indicates that to take course 0 you have to first take course 1.

Return true if you can finish all courses. Otherwise, return false.

 

Example 1:

Input: numCourses = 2, prerequisites = [[1,0]]
Output: true
Explanation: There are a total of 2 courses to take. 
To take course 1 you should have finished course 0. So it is possible.

Example 2:

Input: numCourses = 2, prerequisites = [[1,0],[0,1]]
Output: false
Explanation: There are a total of 2 courses to take. 
To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.

 

Constraints:

  • 1 <= numCourses <= 105
  • 0 <= prerequisites.length <= 5000
  • prerequisites[i].length == 2
  • 0 <= ai, bi < numCourses
  • All the pairs prerequisites[i] are unique.

Solution

/**
* @param {number} numCourses
* @param {number[][]} prerequisites
* @return {boolean}
*/
var canFinish = function(numCourses, prerequisites) {
// construct adjacency graph
const graph = Array(numCourses).fill(null).map(() => []);
const indegree = Array(numCourses).fill(0);
for (const [vin, vout] of prerequisites) {
graph[vout].push(vin);
indegree[vin]++;
}

// initialize queue with courses that has no prerequisites
const queue = [];
for (let i = 0; i < numCourses; i++) {
if (!indegree[i]) {
queue.push(i);
}
}

// test if a topological sort exists using BFS
let count = 0;
while (queue.length) {
const v = queue.shift();
count++;
for (const u of graph[v]) {
indegree[u]--;
if (indegree[u] === 0) {
queue.push(u);
}
}
}
return count === numCourses;
};

We will implement a topological sort solution (this problem essentially reduces to detecting cycles in a directed graph). There are many ways to approach this, but we will use Kahn's algorithm as it is the simplest. More specifically, we will construct a adjacency graph and test whether there exists a topological sort. If there exists a cycle in graph, the nodes in said cycle will never be added into queue since its indegree will never be 0 (and so count will not be incremented for those nodes). On the other hand, if no cycles exist, the indegree of every node will eventually reach 0, and so count will account for every node (ie. count == numCourses).