Parallel Courses Ii

Solution For Parallel Courses Ii

Problem:

Given the total number of courses and a list of prerequisite pairs, return the minimum number of semesters needed to take all courses. The course requirements are expressed as a pair of courses where the first course is a prerequisite for the second course. It is guaranteed that all prerequisites are unique.

You may assume that there are no duplicate edges in the input prerequisites.

Example 1:

Input: n = 3, dependencies = [[1,3],[2,3]] Output: 2
Explanation:
In the first semester, courses 1 and 2 are taken. In the second semester, course 3 is taken.

Example 2:

Input: n = 3, dependencies = [[1,2],[2,3],[3,1]] Output: -1
Explanation:
No course can be taken because they depend on each other.

Solution:

This problem can be solved by topological sorting. We will use a variation of Kahn’s algorithm to find the topological order of the graph. In order to calculate the minimum number of semesters, we will group the courses into semesters. Each semester can contain multiple courses.

Step 1: Create a graph using the given dependencies

We will create a directed graph using the given dependencies. Each course will be a node in the graph and its prerequisites will be its incoming edges.

Step 2: Calculate the in-degree of each node

We will calculate the in-degree of each node (i.e., the number of incoming edges). We will use an array of size n to store this information.

Step 3: Create a queue and add all nodes with zero in-degree

We will create a queue and add all nodes with zero in-degree to it. These are the nodes that can be taken in the first semester.

Step 4: Process the queue and update the in-degree of neighboring nodes

We will process the queue and update the in-degree of all neighboring nodes. If a neighboring node has zero in-degree after removing the edge, we will add it to the queue. We will repeat this process until the queue is empty.

Step 5: Increment the semester counter and repeat Step 4

After processing the queue, we will increment the semester counter and repeat Step 4. The nodes in the queue will represent the courses that can be taken in the current semester.

Step 6: Check if all courses have been taken

If all courses have been taken, we will return the semester counter. Otherwise, we will return -1 to indicate that all courses cannot be taken.

Implementation:

Here is the Python implementation of the above algorithm:

def parallelCourses(n: int, dependencies: List[List[int]]) -> int:
# Step 1: Create a graph using the given dependencies
graph = [[] for _ in range(n)] for u, v in dependencies:
graph[u – 1].append(v – 1)

# Step 2: Calculate the in-degree of each node
in_degree = [0] * n
for u in range(n):
    for v in graph[u]:
        in_degree[v] += 1

# Step 3: Create a queue and add all nodes with zero in-degree
queue = []
for u in range(n):
    if in_degree[u] == 0:
        queue.append(u)

# Initialize the semester counter
semesters = 0

# Step 4: Process the queue and update the in-degree of neighboring nodes
while queue:
    # Increment the semester counter
    semesters += 1

    # Take all the courses in the current semester
    for _ in range(len(queue)):
        u = queue.pop(0)

        # Step 5: Update the in-degree of neighboring nodes
        for v in graph[u]:
            in_degree[v] -= 1

            # Add the node to the queue if its in-degree becomes zero
            if in_degree[v] == 0:
                queue.append(v)

# Step 6: Check if all courses have been taken
if sum(in_degree) == 0:
    return semesters
else:
    return -1

Time Complexity: O(n + m), where n is the number of courses and m is the number of dependencies. We traverse each node and edge only once.

Space Complexity: O(n + m), where n is the number of courses and m is the number of dependencies. We use an array of size n to store the in-degree information and a queue of size m at most to store the nodes. We also use a graph of size m to represent the dependencies.

Step by Step Implementation For Parallel Courses Ii

There are a total of n courses you have to take, labeled from 0 to n - 1.

Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?

//Solution

class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        
        //Create an array of ArrayList's to represent the graph
        ArrayList[] graph = new ArrayList[numCourses];
        
        //Initialize the graph
        for(int i = 0; i < numCourses; i++) {
            graph[i] = new ArrayList();
        }
        
        //Add edges to the graph
        for(int i = 0; i < prerequisites.length; i++) {
            graph[prerequisites[i][1]].add(prerequisites[i][0]);
        }
        
        //Create an array to track visited nodes
        boolean[] visited = new boolean[numCourses];
        
        //Create an array to track whether a node is currently being visited (to detect cycles)
        boolean[] visiting = new boolean[numCourses];
        
        //Loop through each node in the graph
        for(int i = 0; i < numCourses; i++) {
            //If the node has not been visited yet, visit it
            if(!visited[i]) {
                //If visiting the node results in a cycle, return false
                if(visit(graph, visited, visiting, i)) {
                    return false;
                }
            }
        }
        
        //If we reach this point, then there are no cycles and all nodes can be visited, so return true
        return true;
    }
    
    //DFS helper function
    public boolean visit(ArrayList[] graph, boolean[] visited, boolean[] visiting, int node) {
        //Mark the node as being visited
        visiting[node] = true;
        
        //Loop through each neighbor of the node
        for(int neighbor : graph[node]) {
            //If the neighbor is currently being visited, then there is a cycle, so return true
            if(visiting[neighbor]) {
                return true;
            }
            //If the neighbor has not been visited yet, visit it
            if(!visited[neighbor]) {
                //If visiting the neighbor results in a cycle, return true
                if(visit(graph, visited, visiting, neighbor)) {
                    return true;
                }
            }
        }
        
        //Mark the node as visited and remove it from the visiting array
        visited[node] = true;
        visiting[node] = false;
        
        //Return false since there is no cycle
        return false;
    }
}
There are a total of n courses you have to take, labeled from 0 to n-1.

Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses.

There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.

Example 1:

Input: 2, [[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] .
Example 2:

Input: 4, [[1,0],[2,0],[3,1],[3,2]]
Output: [0,1,2,3] or [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] .
Note:

The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
You may assume that there are no duplicate edges in the input prerequisites.
There are a total of n courses you have to take, labeled from 0 to n-1.

Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses.

If there are many valid orders, you may return any of them. If it is impossible to finish all courses, return an empty array.

//Solution:

var findOrder = function(numCourses, prerequisites) {
    
    //Create an array to store the order of courses
    var order = [];
    
    //Create a course graph using an adjacency list
    //The key is the course and the value is an array of prerequisites
    var courseGraph = {};
    
    //Create a visited array to keep track of visited courses
    var visited = {};
    
    //Loop through the prerequisites and add them to the course graph
    for(var i = 0; i < prerequisites.length; i++) {
        //Get the course and prerequisite
        var course = prerequisites[i][0];
        var prerequisite = prerequisites[i][1];
        
        //If the course is not in the course graph, add it
        if(!courseGraph[course]) {
            courseGraph[course] = [prerequisite];
        }
        //Otherwise, push the prerequisite into the array
        else {
            courseGraph[course].push(prerequisite);
        }
    }
    
    //Loop through the courses
    for(var i = 0; i < numCourses; i++) {
        //If the course has not been visited, visit it
        if(!visited[i]) {
            //Visit the course
            if(!visit(i, courseGraph, visited, order)) {
                return [];
            }
        }
    }
    
    //Return the order
    return order;
};

//Function to visit a course
var visit = function(course, courseGraph, visited, order) {
    //Set the course to visited
    visited[course] = true;
    
    //If the course has any prerequisites
    if(courseGraph[course]) {
        //Loop through the prerequisites
        for(var i = 0; i < courseGraph[course].length; i++) {
            //Get the prerequisite
            var prerequisite = courseGraph[course][i];
            
            //If the prerequisite has not been visited, visit it
            if(!visited[prerequisite]) {
                //Visit the prerequisite
                if(!visit(prerequisite, courseGraph, visited, order)) {
                    return false;
                }
            }
            //If the prerequisite has been visited, but is not in the order array, then there is a cycle
            else if(!order.includes(prerequisite)) {
                return false;
            }
        }
    }
    
    //Add the course to the order array
    order.unshift(course);
    
    //Return true
    return true;
};
There are a total of n courses you have to take, labeled from 0 to n-1.

Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses.

There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.

Example 1:

Input: 2, [[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] .
Example 2:

Input: 4, [[1,0],[2,0],[3,1],[3,2]]
Output: [0,1,2,3] or [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] .
Note:

The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
You may assume that there are no duplicate edges in the input prerequisites.
There are a total of n courses you have to take, labeled from 0 to n-1.

Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses.

There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.

Example 1:

Input: 2, [[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] .
Example 2:

Input: 4, [[1,0],[2,0],[3,1],[3,2]]
Output: [0,1,2,3] or [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] .
Note:

The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
You may assume that there are no duplicate edges in the input prerequisites.
Scroll to Top

Top 100 Leetcode Practice Problems In Java

Get 30% Off Instantly!
[gravityforms id="5" description="false" titla="false" ajax="true"]