Course Schedule asks a yes/no question hiding a classic graph idea: given courses and their prerequisites, can you order them so every course comes after the ones it depends on? You can — unless the prerequisites loop back on themselves. Detecting that loop is topological sort.
Problem. There are num courses labeled 0 … num-1. Each pair [course, pre] means you must take
pre before course. Return true if you can finish all the courses, and false if it is impossible.
Example: num = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]. Read as arrows 0→1, 0→2, 1→3, 2→3.
There is no loop, so the answer is true.
The idea
Think of the courses as a directed graph: draw an arrow from pre to course. "Can I finish
everything?" becomes "does this graph have a cycle?" If course A needs B and B needs A, you are stuck
forever — that loop is the only thing that makes the answer false.
Kahn's algorithm finds the loop by trying to peel the graph apart, layer by layer:
- For each course, count its in-degree — how many arrows point into it. That is how many prerequisites it still has waiting.
- A course with in-degree 0 has no unmet prerequisites, so it is ready — you can take it now. Put all such courses in a queue.
- Repeatedly take a ready course, mark it finished, and "remove" it: for every course it pointed to, drop one prerequisite (decrement its in-degree). If that drops a neighbor to 0, it becomes ready too.
If you manage to finish all num courses this way, there was no cycle. If the queue empties early —
some courses never reached in-degree 0 — those courses are tangled in a loop, so the answer is false.
The key insight: a course is safe to finish the moment its in-degree hits 0, because that means every prerequisite has already been finished ahead of it.
Walk through it
Step through the animation. Each node's badge is its current in-degree. We seed the queue with course
0 (the only in-degree-0 course), finish it, and watch its arrows disappear — that drops 1 and 2 to 0,
so they join the queue. Finishing 1 and 2 drops 3 to 0 last of all. The done counter climbs to 4,
which equals num, so we return true.
Pseudocode
compute in-degree of every course (arrows pointing in)
queue = all courses whose in-degree is 0
done = 0
while queue is not empty:
take a course off the queue
done = done + 1
for each neighbor it points to:
decrement that neighbor's in-degree
if the neighbor's in-degree is now 0:
add it to the queue
return (done == number of courses)The Python solution
def can_finish(num, prerequisites):
indeg = [0] * num
adj = [[] for _ in range(num)]
for course, pre in prerequisites:
adj[pre].append(course)
indeg[course] += 1
queue = [c for c in range(num) if indeg[c] == 0]
done = 0
while queue:
node = queue.pop(0)
done += 1
for nxt in adj[node]:
indeg[nxt] -= 1
if indeg[nxt] == 0:
queue.append(nxt)
return done == numindeg[c]is how many prerequisites coursecstill has;adj[pre]lists the courses that depend onpre. We build both in one pass overprerequisites.queuestarts with every course that already has in-degree 0 — the courses ready from the very start.- The
whileloop is the heart: pop a ready course, count it asdone, then walk its neighbors and decrement each in-degree. A neighbor that reaches 0 is now ready, so it goes on the queue. - At the end,
done == numistrueonly if every course came off the queue. If a cycle trapped some courses, they never reached in-degree 0,donefalls short, and we returnfalse.
Complexity
| Case | Time | Notes |
|---|---|---|
| Build graph + in-degrees | O(V + E) (moderate) | one pass over courses and edges |
| Kahn's loop | O(V + E) (moderate) | each node and edge handled once |
O(V + E) (moderate)V is the number of courses and E the number of prerequisite pairs. We touch each course once and each
arrow once, so the whole thing is O(V + E) time and space.
When this pattern shows up
Any problem about ordering tasks with dependencies — build systems, course plans, package installs, "which job runs first" — is a topological sort in disguise. Two standard tools: Kahn's algorithm (in-degrees + queue, shown here) or DFS with a visiting/visited marker. If the question only asks can it be done (not the order), you are really being asked is there a cycle?
Mind the arrow direction. [course, pre] means pre → course, so the in-degree is on course. If
you flip the edge, every in-degree is wrong and the algorithm silently gives the opposite answer. Also
remember: the answer is false only when a cycle exists — a graph can have many valid orders and any
one of them is fine.
Practice
After we finish course 0 and remove its two arrows, what are the in-degrees of courses 1, 2, and 3?
1. What does a course's in-degree represent?
2. When is a course ready to be finished?
3. How does Kahn's algorithm detect that finishing all courses is impossible?
4. What is the time complexity of this solution?