Pattern #54

Topological Sort

Important interview questions, thinking patterns, Kahn's Indegree 0 Queue, DFS Postorder Reverse, Alien Dictionary edge cases, Parallel Course layers, and Go templates.

Must Solve

15 core questions — solve these first.

  1. 1.Course Schedule
    medium
  2. 2.Course Schedule II
    medium
  3. 3.Alien Dictionary
    hard
  4. 4.Find Eventual Safe States
    medium
  5. 5.Minimum Height Trees — related ordering idea
    medium
  6. 6.Parallel Courses
    medium
  7. 7.Parallel Courses III
    hard
  8. 8.Find All Possible Recipes from Given Supplies
    medium
  9. 9.Build Order / Dependency Order
    medium
  10. 10.Sequence Reconstruction
    medium
  11. 11.Sort Items by Groups Respecting Dependencies
    hard
  12. 12.Largest Color Value in a Directed Graph
    hard
  13. 13.Minimum Time to Complete All Tasks
    medium
  14. 14.Find Eventual Safe States
    medium
  15. 15.Directed Graph Cycle Detection
    medium

Also Important

9 more questions worth practicing.

  1. 16.Topological Sort Using Kahn's Algorithm
    medium
  2. 17.Topological Sort Using DFS
    medium
  3. 18.Detect Cycle in Directed Graph
    medium
  4. 19.Build Systems Dependency Ordering
    medium
  5. 20.Package Installation Order
    medium
  6. 21.Task Scheduling With Prerequisites
    medium
  7. 22.Strongly Connected Components — advanced relation
    hard
  8. 23.Critical Path in DAG
    hard
  9. 24.Shortest Path in DAG
    medium

How to Think

  1. Prerequisites / dependencies?Directed Graph + Topological Sort
  2. Need valid execution order?Topological Sort
  3. Need detect dependency cycle?Topological Sort fails (processedCount < n)
  4. Process nodes as prerequisites complete?Kahn's Algorithm (Indegree 0 Queue)

Go Topological Sort Templates

Kahn's Indegree 0 Queue & DFS Postorder Reverse in Go

// 1. Kahn's Algorithm (BFS Indegree 0 Queue): O(V + E) Time
func topoSortKahn(n int, edges [][]int) []int {
    adj := make([][]int, n)
    indegree := make([]int, n)

    for _, e := range edges {
        u, v := e[0], e[1] // Edge u -> v means u before v
        adj[u] = append(adj[u], v)
        indegree[v]++
    }

    queue := []int{}
    for i := 0; i < n; i++ {
        if indegree[i] == 0 {
            queue = append(queue, i) // Ready nodes!
        }
    }

    order := []int{}
    head := 0

    for head < len(queue) {
        u := queue[head]
        head++
        order = append(order, u)

        for _, v := range adj[u] {
            indegree[v]--
            if indegree[v] == 0 {
                queue = append(queue, v) // Prerequisite satisfied!
            }
        }
    }

    if len(order) != n {
        return nil // Cycle detected! Not all nodes processed.
    }
    return order
}

// 2. DFS Topological Sort (Postorder Reverse): O(V + E) Time
func topoSortDFS(n int, adj [][]int) []int {
    state := make([]int, n) // 0=unvisited, 1=visiting, 2=finished
    order := []int{}

    var dfs func(u int) bool
    dfs = func(u int) bool {
        if state[u] == 1 { return false } // Cycle!
        if state[u] == 2 { return true }

        state[u] = 1
        for _, v := range adj[u] {
            if !dfs(v) { return false }
        }
        state[u] = 2
        order = append(order, u) // Postorder append!
        return true
    }

    for i := 0; i < n; i++ {
        if state[i] == 0 && !dfs(i) {
            return nil
        }
    }

    // Reverse order array to get valid Topological Order
    for i, j := 0, len(order)-1; i < j; i, j = i+1, j-1 {
        order[i], order[j] = order[j], order[i]
    }
    return order
}

👉 Total Time: O(V + E) | Space: O(V + E) graph + queue/stack

Kahn's Algorithm (Indegree 0 Queue)

1. Indegree Definition: Indegree is the number of incoming prerequisite edges pointing into a node.

2. Ready Queue: Initialize a queue with all nodes having indegree == 0 (nodes with no remaining prerequisites).

3. Processing Loop:Pop a node, append to output order, and decrement the indegree of all outgoing neighbors. Whenever a neighbor's indegree reaches 0, enqueue it immediately!

4. Cycle Detection: If len(order) < n when the queue empties, nodes trapped inside a dependency cycle never reach indegree 0, proving a cycle exists!

DFS Postorder Reverse & Parallel Waves

1. DFS Postorder Reverse: Recurse into all neighbors first, append the current node to the order array AFTER children finish, and REVERSE the result at the end. Use a 3-state array (0=unvisited, 1=visiting, 2=finished) to detect directed cycles.

2. Parallel Course Waves: In Kahn's BFS, taking the queue size at each level loop calculates the minimum number of parallel semesters/waves needed to complete all tasks (Parallel Courses).

Visual Memory Rule
Topological Sort → Valid linear ordering for DAGs where u -> v implies u before v
Kahn's Algo      → Indegree 0 Queue -> Decrement neighbors -> Enqueue new 0s
Kahn Cycle Check → len(order) < n implies dependency deadlock cycle!
DFS Method       → Postorder append -> REVERSE final array
Alien Dict       → Compare adjacent words -> Build char topo graph

💡 Golden Rule: "A node becomes ready only when all of its prerequisites are finished; repeatedly process ready nodes until everything is ordered."

Common Interview Mistakes

1. Using Topo Sort on Undirected Graph

Topological sorting requires directed edges! It is exclusively defined on Directed Acyclic Graphs (DAGs).

2. Forgetting Cycle Length Check

In Kahn's algorithm, if a cycle exists, the output array will be shorter than n. Always check len(order) == n.

3. Building Edge Directions Backwards

If "Course A requires B", the edge MUST be B -> A (B before A). Reversing direction corrupts indegree counts!

4. Forgetting to Reverse DFS Result

DFS postorder appends nodes after visiting children, producing a REVERSE topological order. You MUST reverse the array at the end!

Interview Rules

  1. 1. Prerequisites / Dependencies? → Directed Graph Topological Sort
  2. 2. Kahn's Algorithm? → Queue initialized with indegree == 0 nodes
  3. 3. Processing step? → Pop node, append to order, decrement neighbor indegrees, enqueue new 0s
  4. 4. Cycle validation? → If len(order) < n $\implies$ Cycle exists (return empty/nil)
  5. 5. Course Schedule II? → Return valid topological order array
  6. 6. Alien Dictionary? → Build char dependency graph from adjacent word diffs + Topo Sort
  7. 7. Parallel execution waves? → Kahn BFS queue size level rings
  8. 8. Overall Complexity → Time: O(V + E) | Space: O(V + E)

Small Rules

  1. Rule 1: Topological sort is defined exclusively on Directed Acyclic Graphs (DAGs).
  2. Rule 2: Indegree 0 nodes are ready to execute because all prerequisites are satisfied.
  3. Rule 3: Processing a node reduces incoming prerequisite counts of its neighbors.
  4. Rule 4: DFS topological sorting requires postorder append followed by reversing the result.
  5. Rule 5:Having >1 node in Kahn's queue implies multiple valid topological orders exist.

Production Thinking

Build System Compilation OrderDetermining module build sequence in Bazel, Webpack, and Cargo

Deployment Service SequenceOrdering microservice database migrations & backend deployment stages

Workflow Engine ExecutionExecuting DAG task pipelines in Apache Airflow & Temporal

Data Pipeline Stage SchedulingEnsuring raw data cleaning runs prior to AI model training stages

Remember This

Topological Sort → Dependency Order for DAGs
u -> v           → u before v
Kahn's Algo      → Indegree 0 Queue
Indegree 0       → Ready to execute
Process          → Decrease neighbors' indegree
New 0            → Enqueue
Processed < N    → Cycle Deadlock!
DFS Method       → Postorder append -> REVERSE
Time             → O(V + E)

💡 Golden Rule: "A node becomes ready only when all of its prerequisites are finished; repeatedly process ready nodes until everything is ordered."