Course Schedule II


Link : Course Schedule II – LeetCode


1. Problem Statement

You are given:

Return:


2. Examples

Example 1:

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

Example 2:

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

3. Constraints


4. Intuition

This problem is a classical application of Topological Sorting of a Directed Acyclic Graph (DAG).

Why topological sorting?

We need to order courses such that prerequisites are completed before dependent courses.
Topological order guarantees that if there's an edge from u → v, then u appears before v in the ordering.


5. Why It Only Works on DAGs

Topological Sort only works on DAGs (Directed Acyclic Graphs) because:

Example of a cycle:

[0 → 1], [1 → 2], [2 → 0]

No course can start without the previous being completed – this is impossible.


6. Approach 1: Kahn's Algorithm (BFS Topological Sort)

Algorithm:

  1. Build the adjacency list

  2. Compute in-degree of each node

  3. Push all nodes with in-degree 0 to a queue

  4. While the queue is not empty:

    • Pop node and add to result

    • Decrease in-degree of its neighbors

    • If neighbor’s in-degree becomes 0, push it to the queue

  5. If result size equals numCourses → valid ordering
    Else → cycle exists → return []


7. Java Code: BFS (Kahn's Algorithm)

class Solution {
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        List<List<Integer>> adj = new ArrayList<>();
        for(int i = 0; i < numCourses; i++) {
            adj.add(new ArrayList<>());
        }

        int[] indegree = new int[numCourses];
        for(int[] pre : prerequisites) {
            int u = pre[1], v = pre[0];
            adj.get(u).add(v);
            indegree[v]++;
        }

        Queue<Integer> q = new LinkedList<>();
        for(int i = 0; i < numCourses; i++) {
            if(indegree[i] == 0) q.offer(i);
        }

        int[] result = new int[numCourses];
        int idx = 0;

        while(!q.isEmpty()) {
            int u = q.poll();
            result[idx++] = u;
            for(int v : adj.get(u)) {
                indegree[v]--;
                if(indegree[v] == 0) q.offer(v);
            }
        }

        return idx == numCourses ? result : new int[0];
    }
}

8. Dry Run Example

Input:

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

Adjacency List:

0 → [1, 2]
1 → [3]
2 → [3]

In-degree:

0 → 0
1 → 1
2 → 1
3 → 2

Steps:

Final result = [0,1,2,3] (or [0,2,1,3] — both valid)


9. Time and Space Complexity

Type Complexity
Time O(V + E) — visit each node and edge once
Space O(V + E) — for adjacency list and queue

10. Optional: DFS-Based Topological Sort

If needed, the DFS-based approach can be implemented using: