Leetcode 210. Course Schedule II
You are given a total of numCourses
courses labeled from 0
to numCourses-1
. You are also given an array of prerequisites where prerequisites[i] = [a_i, b_i]
indicates that you must take course b_i
before course a_i
.
[0, 1]
, indicates that to take course 0
, you have to first take course 1
.Return the ordering of courses you should take to finish all courses. If there are many valid answers, return any of them. If it is impossible to finish all courses, return an empty array.
Input: numCourses = 2, prerequisites = [[1,0]]
Output: [0,1]
Explanation: There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is [0,1].
Input: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]
Output: [0,2,1,3]
Explanation: There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. Another correct ordering is [0,2,1,3].
(a_i, b_i)
are distinct.This problem is a classic application of topological sorting for Directed Acyclic Graphs (DAG). Here is the overall strategy to be implemented:
import java.util.*;
public class Solution {
public int[] findOrder(int numCourses, int[][] prerequisites) {
// Step 1: Initialize data structures
List<List<Integer>> adjList = new ArrayList<>();
int[] inDegree = new int[numCourses];
for (int i = 0; i < numCourses; i++) {
adjList.add(new ArrayList<>());
}
// Step 2: Build the graph
for (int[] prereq : prerequisites) {
int dest = prereq[0];
int src = prereq[1];
adjList.get(src).add(dest);
inDegree[dest]++;
}
// Step 3: Queue of all courses with no prerequisites (in-degree 0)
Queue<Integer> queue = new LinkedList<>();
for (int i = 0; i < numCourses; i++) {
if (inDegree[i] == 0) {
queue.add(i);
}
}
// Step 4: Process the nodes
int[] order = new int[numCourses];
int index = 0;
while (!queue.isEmpty()) {
int currentCourse = queue.poll();
order[index++] = currentCourse;
// Reduce the in-degree of neighboring nodes
for (int neighbor : adjList.get(currentCourse)) {
inDegree[neighbor]--;
if (inDegree[neighbor] == 0) {
queue.add(neighbor);
}
}
}
// Step 5: Check if all nodes were processed
return index == numCourses ? order : new int[0];
}
public static void main(String[] args) {
Solution sol = new Solution();
System.out.println(Arrays.toString(sol.findOrder(4, new int[][]// use example above
System.out.println(Arrays.toString(sol.findOrder(2, new int[][]// use example above
System.out.println(Arrays.toString(sol.findOrder(2, new int[][]// use example above
}
}
This approach ensures efficient processing and correctly handles the detection of cycles in the graph.
Got blindsided by a question you didn’t expect?
Spend too much time studying?
Or simply don’t have the time to go over all 3000 questions?