Course Schedule II

Problem

https://leetcode.com/problems/course-schedule-ii/description/

Intution

Time and Space complexity

Code

class Solution {
    public int[] findOrder(int numCourses, int[][] prerequisites) {     
        // V -> Vertices, E -> Edges
        // Time Complexity: O(V+E), have to iterate through all the vertices and edges
        // Space Complexity: O(V), in the worsr case the dfs might have to backtrack all the vertices  
        // Set up adjacency list
        Map<Integer, List<Integer>> graph = new HashMap<>();
        
        // Set up nodes/course
        for(int i=0;i<=numCourses;i++) {
            graph.put(i, new ArrayList<>());
        }
        
        // Populate directed graph
        for(int i=0;i<prerequisites.length;i++) {
            graph.get(prerequisites[i][1]).add(prerequisites[i][0]);
        }
        
        // Setup a tracker with three states
        /*
            0 -> Unprocessed
            1 -> Processed
            -1 -> Currently processing
        */
        int[] visited = new int[numCourses];
        
        // Set up a stack to get order of courses that is being processed
        Stack<Integer> stack = new Stack<>();
        
        // Set up a flag to represent if the course can be completed or not
        boolean possible = true;
        
        // Process the course
        for(int i=0;i<numCourses;i++) {
            if(!isValidSchedule(graph, visited, i, stack)) {
                possible = false;
                break;
            }
        }
        
        if(possible) {
        // If its possible then give the order of the course
        int[] orderOfCourses = new int[numCourses];
            int i=0;
            while(!stack.isEmpty()) {
             orderOfCourses[i++] = stack.pop();
            }
            return orderOfCourses;
        }
        
        return new int[]{};
    }

    private boolean isValidSchedule(Map<Integer, List<Integer>> graph, int[] visited, int course, Stack<Integer> stack) {
        // Handle cycles and previously processed course
        if(visited[course]!=0) {
            return visited[course] == 1;
        }
        
        // Mark the current course for processing 
        visited[course] = -1;
        
        // Check for the dependent courses have any cycles
        for(int nextCourse: graph.get(course))  {
            if(!isValidSchedule(graph, visited, nextCourse, stack)) {
                return false;
            }
        }
        
        stack.push(course); // Push the course to stack to maintain order
        visited[course] = 1; // Mark the course as processed completly
        return true;
    }
}

Last updated

Was this helpful?