Blind 75Medium

Course Schedule — Topological Sort with Cycle Detection

Use Kahn’s algorithm (BFS) or DFS to detect cycles in the prerequisite graph and decide feasibility.

GraphTopological Sort

Problem Statement

Given the number of courses and prerequisite pairs, determine if all courses can be completed.

Why This Problem Matters

  • Classic application of topological sorting and cycle detection.
  • Reinforces understanding of in-degree counts and graph traversal.
  • Serves as the basis for scheduling and dependency resolution problems.

Thought Process

Model as directed graph

Edge from prerequisite to course; cycle implies impossible completion.

Apply topological sort

Kahn’s algorithm removes nodes with in-degree zero, simulating course completion.

Check processed count

If all courses processed, schedule feasible; otherwise a cycle exists.

Step-by-Step Reasoning

  1. Build adjacency list and in-degree array.
  2. Seed queue with all nodes having in-degree zero.
  3. Pop queue, decrement in-degree of neighbors; enqueue when they reach zero.
  4. Return true if processed count equals numCourses.

Dry Run

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

Order 0→1 processed; feasible.

prerequisites = [[1,0],[0,1]]

Queue empties early; processed < numCourses → cycle detected.

Complexity Analysis

Time

O(V + E)

Space

O(V + E)

Why

Graph traversal visits each node and edge once.

Annotated Solution

JAVA
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;

public class CourseSchedule {
  public boolean canFinish(int numCourses, int[][] prerequisites) {
    List<List<Integer>> graph = new ArrayList<>();
    for (int i = 0; i < numCourses; i += 1) {
      graph.add(new ArrayList<>());
    }

    int[] indegree = new int[numCourses];
    for (int[] edge : prerequisites) {
      int course = edge[0];
      int prereq = edge[1];
      graph.get(prereq).add(course);
      indegree[course] += 1;
    }

    ArrayDeque<Integer> queue = new ArrayDeque<>();
    for (int i = 0; i < numCourses; i += 1) {
      if (indegree[i] == 0) {
        queue.addLast(i);
      }
    }

    int processed = 0;
    while (!queue.isEmpty()) {
      int node = queue.removeFirst();
      processed += 1;
      for (int neighbor : graph.get(node)) {
        indegree[neighbor] -= 1;
        if (indegree[neighbor] == 0) {
          queue.addLast(neighbor);
        }
      }
    }

    return processed == numCourses;
  }
}

Kahn’s algorithm systematically removes nodes without prerequisites, revealing cycles when nodes remain with non-zero in-degree.

Common Pitfalls

  • Building edges in wrong direction prevents correct in-degree computations.
  • Forgetting to increment processed count or to check equality leads to false positives.
  • DFS alternatives require three-color marking; ignoring state leads to infinite recursion.

Follow-Up Questions

  • How would you output a valid order if it exists? (Return the topological order.)
  • Can you detect which courses are part of the cycle?

Key Takeaways

Topological sorting is the go-to technique for prerequisite graphs.
Always state the complexity in terms of vertices and edges.
Queue-based BFS version avoids recursion depth issues.