Data structures problem 28 of 30

Course schedule

  • Data structures
  • Hard

There are n courses numbered 0 to n − 1. Each pair [course, before] means you must take before first. Write can_finish(n, prereqs) that returns whether it is possible to take every course.

can_finish(2, [[1, 0]])            # True
can_finish(2, [[1, 0], [0, 1]])    # False (a cycle)
Show hint

This is a directed graph. Repeatedly take any course with no remaining prerequisites. If you get stuck before taking everything, there must be a cycle.

Show solution
from collections import deque

def can_finish(n, prereqs):
    needs = [0] * n
    unlocks = [[] for _ in range(n)]
    for course, before in prereqs:
        needs[course] += 1
        unlocks[before].append(course)
    ready = deque(c for c in range(n) if needs[c] == 0)
    done = 0
    while ready:
        c = ready.popleft()
        done += 1
        for nxt in unlocks[c]:
            needs[nxt] -= 1
            if needs[nxt] == 0:
                ready.append(nxt)
    return done == n

This is Kahn's algorithm for topological sorting. needs counts unmet prerequisites; finishing a course unlocks the ones that depended on it. Courses in a cycle never reach zero, so done falls short. O(n + number of prerequisites). Build tools and package managers solve the same problem to order their steps.

Want a problem like this every day? See today's problem and keep a streak going.