Skip to content
AI360Xpert
Beta
Difficulty: MediumGraphs

Course Schedule II

Problem in Plain English

Given a course count and prerequisite pairs, return any order in which all courses can be finished, or an empty array when a cycle makes it impossible.

Problem Statement

You are given numCourses courses labeled 0 to numCourses - 1 and prerequisites prerequisites[i] = [a, b] meaning course b comes before course a.

Return any ordering that respects every prerequisite, or an empty array when no such ordering exists.

Constraints

  • 1 <= numCourses <= 2000
  • 0 <= prerequisites.length <= numCourses * (numCourses - 1)
  • prerequisites[i].length == 2
  • 0 <= a, b < numCourses
  • Each pair has distinct course labels a and b; all prerequisite pairs are unique.

Examples

Example 1

Input
numCourses = 2, prerequisites = [[1,0]]
Output
[0,1]

Course 0 has no prerequisites, so taking 0 then 1 respects the single dependency.

Example 2

Input
numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]
Output
[0,2,1,3]

After 0, courses 1 and 2 are both ready; either may come first. Course 3 must follow both. Thus [0,2,1,3] and [0,1,2,3] are equally valid outputs.

Example 3

Input
numCourses = 1, prerequisites = []
Output
[0]

With no prerequisites the lone course stands alone in the order.

Example 4

Input
numCourses = 3, prerequisites = [[1,0],[0,1]]
Output
[]

Courses 0 and 1 depend on each other. Course 2 is independently available, but finishing only it is insufficient: a full order is impossible, so return no order.

Intuition

A prerequisite is a directed constraint: [1,0] says 0 must precede 1. A valid order exists exactly when these constraints have no directed cycle. You can finish a course after exploring all of its prerequisites, or repeatedly take a course whose unfinished prerequisite count is zero. The first strategy uses DFS finish order; the second uses a queue of ready courses. Multiple ready courses can be chosen in any order.

Approaches

DFS Postorder

Solution Details

Reveal DFS Postorder: intuition, complexity, and code

Hints

Hint 1
Read each pair [a, b] as a directed edge from b to a, since b must come first.
Hint 2
Emit a course into the answer the moment all of its prerequisites are already emitted.
Hint 3
If emitted courses fall short of numCourses, a cycle blocks the rest, so return the empty array.

Edge Cases

  • No prerequisites means any order works, such as 0 through numCourses - 1 in sequence.
  • A single course with no prerequisites returns [0].
  • Outside the stated distinct-label constraint, a self-loop pair such as [0, 0] can never be scheduled and must return [].
  • A cycle in one disconnected component makes the whole schedule impossible even when other courses have no prerequisites.
  • A chain of 2000 courses checks traversal depth; the explicit DFS stack and queue run at default runtime settings.

Common Mistakes and Interview Tips

  • Returning a partial order when a cycle exists instead of the required empty array.
  • Using course-to-prerequisite edges in Kahn outgoing-dependents adjacency schedules prerequisites after their courses. Its graph must store b to a; DFS deliberately uses the opposite representation.
  • Accepting any single valid order as wrong during testing when many orders are acceptable.
  • Reversing DFS output despite its course-to-prerequisite adjacency. Reverse finish order is appropriate for the opposite edge orientation, not this code.
  • Using only one visited Boolean loses the distinction between an active cycle target and an already finished shared prerequisite.
  • Using JavaScript shift for the queue can add quadratic array movement; a head cursor keeps dequeue constant-time.
  • Recursive Python DFS can exceed the default stack limit on a long legal chain; these snippets use explicit frames.

Key Takeaway

When a problem asks for the order itself rather than just feasibility, emit nodes as their dependencies clear; Kahn construction turns cycle detection into ordering.