Browse curriculum

Ordering Dependencies (Topological Sort)

Order tasks so every dependency comes first, with Kahn's algorithm — and detect a cycle when no such order exists.

Medium
12 min

Examples

Input:n = 6, edges = [[5,2],[5,0],[4,0],[4,1],[2,3],[3,1]]
Output:[4,5,2,0,3,1]
Explain:

4 and 5 wait on nothing, so they go first; every other node follows once its prerequisites are placed. Other valid orders are also accepted.

Input:n = 4, edges = [[0,1],[1,2],[2,3],[3,1]]
Output:[]
Explain:

1, 2 and 3 wait on each other in a cycle, so no order exists.

What is Topological Sort?

Given a Directed Acyclic Graph (DAG), a Topological Sort is a linear ordering of vertices such that for every directed edge u -> v, vertex u comes before vertex v.

It is the standard algorithm for resolving dependencies (e.g., compiling code, scheduling tasks, course prerequisites).

The Motivation: Course Schedule

You need to take N courses. Some courses have prerequisites.

  • Physics II requires Physics I.
  • Calc III requires Calc II requires Calc I.

Goal: Find a valid order to take ALL courses. If impossible (due to a cycle), tell us.

The Cycle Problem

What if you have a cycle?

  • Course A requires Course B.
  • Course B requires Course A.

You can never start! This is a Circular Dependency. A Topological Sort is ONLY possible if the graph has NO Cycles (DAG).

You do not need a separate pass to find out. The walkthrough below orders the graph and, if it cannot, reports the cycle on the way.

When to use Topological Sort?

Pattern Recognition Triggers:

  1. Dependencies: Keywords like "prerequisites", "build order", "depends on".
  2. Linear Ordering: You need to arrange items in a sequence respecting constraints.
  3. Directed Graph: The relationships are one-way.

The Intuition: Find the Start

To start, we must find a node that has NO prerequisites (Indegree = 0).

  1. Pick a node with Indegree == 0. Add it to our sorted list.
  2. "Remove" it from the graph.
  3. When removed, its neighbors' indegrees decrease.
  4. Repeat until all nodes are picked.

This is Kahn's Algorithm.

Interactive Walkthrough (Kahn's Algo)

ARROW u → v = u BEFORE v · NUMBER ABOVE A NODE = PREREQUISITES STILL UNMET · GREEN = PLACED, RED = STUCK ON A CYCLE

COUNT IN-DEGREES

placed

0/6

queued

0

Answer

—

queue (front first)

Empty

order

Nothing placed yet

 

Build the lists from 6 edges and count each node's prerequisites: in-degrees [2, 2, 1, 1, 0, 0]

Next

Queue every node with nothing to wait for: [4, 5]

edges

n

6

Legend & Complexity

The node just taken off the queue

In the queue: nothing left to wait for

Placed — its edges are crossed off

Never reached 0 — waiting on a cycle

Time

O(V + E)

Space

O(V + E)

Each arrow u → v means u must come before v, and the number above a node is its in-degree — how many of its prerequisites are still unmet. Watch it count down as edges are crossed off: a node joins the queue the moment it reaches 0.

Load the Cycle preset to see the other ending. Once 0 is placed, nodes 1, 2 and 3 are each waiting on another of the three, so none of them ever reaches 0 — the queue runs dry, and the code returns []. Kahn's algorithm detects the cycle without looking for it.

Dry Run Table

The figure's default: n = 6, edges 5>2, 5>0, 4>0, 4>1, 2>3, 3>1. In-degrees start as [2, 2, 1, 1, 0, 0] for nodes 0 to 5.

# Queue Take Cross off In-degree changes Order
1 [4, 5] 4 4>0, 4>1 0: 2→1, 1: 2→1 [4]
2 [5] 5 5>2, 5>0 2: 1→0, 0: 1→0 — queue both [4, 5]
3 [2, 0] 2 2>3 3: 1→0 — queue it [4, 5, 2]
4 [0, 3] 0 — — [4, 5, 2, 0]
5 [3] 3 3>1 1: 1→0 — queue it [4, 5, 2, 0, 3]
6 [1] 1 — — [4, 5, 2, 0, 3, 1]

All 6 nodes are placed, so the order is valid. Other valid orders exist — [5, 4, 2, 3, 0, 1] is one — and any of them is a correct answer.

Solution Template (Kahn's)

Kahn's algorithm in all six languages — the lines light up as the figure above steps.

Ordering Dependencies (Topological Sort) Code
1var topologicalSort = function(n, edges) {
2 const graph = Array.from({ length: n }, () => []);
3 const indegree = new Array(n).fill(0);
4 for (const [u, v] of edges) {
5 graph[u].push(v);
6 indegree[v]++;
7 }
8
9 const queue = [];
10 for (let i = 0; i < n; i++) {
11 if (indegree[i] === 0) queue.push(i);
12 }
13 const order = [];
14 let head = 0;
15 while (head < queue.length) {
16 const u = queue[head++];
17 order.push(u);
18 for (const v of graph[u]) {
19 indegree[v]--;
20 if (indegree[v] === 0) queue.push(v);
21 }
22 }
23
24 return order.length === n ? order : [];
25};

Edge Cases & Checks

Critical checks:

  • Cycle: if the order ends with fewer than n nodes, some nodes never reached in-degree 0 — they are waiting on each other. Return [].

  • Disconnected graph: fine. Every component's sources start in the queue together, and their orders interleave.

  • Many valid orders: a topological order is rarely unique. Any order in which every edge points forward is correct.

  • Self-loop: u → u is a one-node cycle. u waits on itself, never reaches 0, and the answer is [].

  • Direction: here [u, v] means u before v. LeetCode's Course Schedule writes [a, b] for "b before a" — build the edge the other way round.

Summary

Recap:

  • Use Indegree to find starting points.
  • Use BFS (Queue) to peel layers.
  • If queue empties and graph still has nodes, there's a Cycle.

The approach, step by step

  1. Count in-degrees

    Build the adjacency lists and count, for every node, how many edges point into it.

  2. Queue the zeros

    Put every node with in-degree 0 in a queue — nothing has to come before them.

  3. Place and cross off

    Take the front node, append it to the order, and decrement each neighbour; queue any neighbour that reaches 0. Return the order if it holds every node, otherwise [].

Frequently asked questions

What is a topological sort?

An ordering of the nodes of a directed graph in which every edge u → v has u before v. It exists exactly when the graph has no cycle, and there are usually several valid orders.


How does Kahn's algorithm detect a cycle?

A node on a cycle is always waiting on another node of the same cycle, so its in-degree never reaches 0 and it is never queued. If the queue empties before all n nodes are in the order, the graph has a cycle.


Should I use Kahn's algorithm or DFS for topological sort?

Both run in O(V + E). Kahn's algorithm builds the order front to back and reports a cycle by leaving nodes unplaced; the DFS version appends each node when it finishes and reverses the list, and needs a separate on-stack check to spot a cycle.

Want to see the mechanism first? Step through it in the visualizer:

Topological Sort

Applying for software engineering roles? Free, no sign-up:

AI resume checker — match your resume to the job description