- Interview Questions
- /
- Problems
- /
- Course Schedule
Course Schedule
Decide whether a set of courses with prerequisites can all be completed. A cycle-detection problem on a directed graph, usually solved with topological sort. Solve it below in Python or JavaScript, then read the walkthrough.
Problem
There are numCourses courses, labeled 0 to numCourses - 1. Each entry [a, b] in prerequisites means you must finish course b before you can start course a.
Return true if there is some order in which you can take every course, and false otherwise.
The same pair may appear more than once. A course that lists itself as its own prerequisite can never be taken.
Example 1
- Input
- numCourses = 4, prerequisites = [[1, 0], [2, 1], [3, 2]]
- Output
- true
Take the courses in the order 0, 1, 2, 3.
Example 2
- Input
- numCourses = 3, prerequisites = [[0, 1], [1, 2], [2, 0]]
- Output
- false
Course 0 needs 1, course 1 needs 2, and course 2 needs 0. None of the three can be started first.
Example 3
- Input
- numCourses = 5, prerequisites = []
- Output
- true
With no prerequisites, any order works.
Constraints
- 1 ≤ numCourses ≤ 2000
- 0 ≤ prerequisites.length ≤ 5000
- prerequisites[i].length == 2
- 0 ≤ a, b < numCourses
Practice
Runs 12 tests in your browser. Python loads on the first run (about 6 MB, then cached). Press ⌘/Ctrl + Enter to run.
Get asked Course Schedule in a real interview?
Interview Solver gives you a working solution live, during your actual coding interview. Invisible to screensharing.
How to solve Course Schedule
Pattern: Topological sort (Kahn’s algorithm)
Treat each course as a node and each prerequisite [a, b] as an edge b → a. You can finish everything exactly when this directed graph has no cycle: a cycle means every course in it is waiting on another course in it, so none of them can go first.
Whenever a problem says "X must happen before Y" and asks whether (or in what order) everything can happen, think topological sort. Kahn's algorithm makes the cycle check concrete: repeatedly take a course with no unfinished prerequisites, mark it done, and lower the prerequisite count of everything that depended on it. If you manage to take all numCourses courses, there was no cycle. If you get stuck with courses left over, the leftovers are tangled in a cycle.
Approach 1: Repeated scanning
Keep a set of finished courses. In each round, scan all prerequisite pairs and finish any course whose prerequisites are all done. Stop when a round makes no progress. Easy to reason about, but each round re-scans every edge, and there can be as many rounds as there are courses.
Time O(V · E) · Space O(V)
Approach 2: DFS with three colors
Build an adjacency list and run a depth-first search from every unvisited course. Mark a node "in progress" when you enter it and "done" when you leave. Reaching an "in progress" node again means you followed a back edge, which is a cycle. Linear time, but in Python a recursive version can hit the default recursion limit on long chains, so you may need an explicit stack.
Time O(V + E) · Space O(V + E)
Approach 3: Kahn’s algorithm (BFS on in-degrees)
- Build an adjacency list
b → [a, ...]and anindegreearray counting each course's prerequisites. - Put every course with
indegree 0into a queue. - Pop a course, count it as taken, and decrement the in-degree of each course that depends on it. Any course that drops to 0 joins the queue.
- When the queue empties, return whether the number taken equals
numCourses.
Courses on a cycle never reach in-degree 0, so they're never counted.
Time O(V + E) · Space O(V + E)
| Approach | Time | Space |
|---|---|---|
| Repeated scanning | O(V · E) | O(V) |
| DFS with three colors | O(V + E) | O(V + E) |
| Kahn’s algorithm (BFS on in-degrees) | O(V + E) | O(V + E) |
Solution code
Try the practice editor first. Both solutions pass every test above.
Course Schedule solution in Python
from collections import deque
def can_finish(num_courses: int, prerequisites: list[list[int]]) -> bool:
graph = [[] for _ in range(num_courses)]
indegree = [0] * num_courses
for course, before in prerequisites:
graph[before].append(course)
indegree[course] += 1
queue = deque(c for c in range(num_courses) if indegree[c] == 0)
taken = 0
while queue:
course = queue.popleft()
taken += 1
for nxt in graph[course]:
indegree[nxt] -= 1
if indegree[nxt] == 0:
queue.append(nxt)
return taken == num_coursesCourse Schedule solution in JavaScript
function canFinish(numCourses, prerequisites) {
const graph = Array.from({ length: numCourses }, () => []);
const indegree = new Array(numCourses).fill(0);
for (const [course, before] of prerequisites) {
graph[before].push(course);
indegree[course]++;
}
const queue = [];
for (let c = 0; c < numCourses; c++) {
if (indegree[c] === 0) queue.push(c);
}
let taken = 0;
for (let head = 0; head < queue.length; head++) {
taken++;
for (const next of graph[queue[head]]) {
indegree[next]--;
if (indegree[next] === 0) queue.push(next);
}
}
return taken === numCourses;
}Common mistakes
- Reversing the edge direction. It happens to give the same yes/no answer here, but it gives the wrong order if you later need to output a schedule.
- Using only "visited" in DFS instead of separate "in progress" and "done" states. A node reached twice through different paths (a diamond) is not a cycle.
- Starting the search only from course 0. The graph can be disconnected, and a cycle can hide in any component.
- Recursing on a 2000-course chain in Python without raising the recursion limit or switching to an explicit stack.
What interviewers look for
Say the reduction out loud first: "courses are nodes, prerequisites are directed edges, and the answer is whether the graph is acyclic." Interviewers want to hear that you recognized the graph problem before you pick an algorithm.
Either DFS with colors or Kahn's algorithm is a full-credit answer. Kahn's is often easier to get right under pressure because it's iterative and the final check is a single count comparison. Walk through a three-node cycle to show that its courses never enter the queue.
Follow-up questions
How would you return an actual order to take the courses?
Record each course as it leaves the queue in Kahn's algorithm. That list is a valid order when its length equals numCourses; otherwise return an empty list. With DFS, append each node when it finishes and reverse the result.
What if you can take several courses per semester and want the minimum number of semesters?
Run Kahn's algorithm level by level: every course in the queue at the start of a round can be taken in the same semester. The number of rounds is the length of the longest prerequisite chain, which is the minimum.
How would you report which courses form the cycle?
With DFS, keep the current path on a stack. When you hit an "in progress" node, the cycle is the slice of the path from that node to the top of the stack.
Companies that ask Course Schedule
Course Schedule is tagged by 132 companies in our interview dataset. The score shows how often it comes up at each company.
- Clevertap100%
- Smarthr100%
- Trimble100%
- Ss C Technologies100%
- Zenefits100%
- Research Innovations100%
- Snyk100%
- Nordstrom100%
- One Medical98%
- Darktrace97%
- Yelp94.2%
- Coupang88.3%
- 10x Genomics88%
- Hashicorp85%
- Clever84%
- Cribl84%
- Mercedes Benz83%
- TikTok82.3%
- Pagerduty81%
- Bear Robotics80%
- Anduril Industries79.6%
- Mts78%
- Prove78%
- Glassdoor77%
and 108 more.
Practice next
Get live help in the real interview
Working solutions in real time during your actual interview. Invisible to screensharing.
Start Free TrialNo credit card required