Skip to content

Commit bdf7b67

Browse files
Merge pull request #292 from ravi0213/issue-287
[ISSUE-287] add program to solve CourseSolution problem
2 parents 8bd2352 + 38b2de0 commit bdf7b67

1 file changed

Lines changed: 91 additions & 0 deletions

File tree

LeetCode/CourseSchedule.java

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import java.io.BufferedReader;
2+
import java.io.IOException;
3+
import java.io.InputStreamReader;
4+
import java.util.*;
5+
6+
/**
7+
* Problem:
8+
* Given N courses, labeled from 0 to N-1. Also given M pairs(X,Y) of prerequisites,
9+
* where Y course must be finished before X.
10+
* We need to tell if it is possible to finish all the courses.
11+
*
12+
* Approach: Topological Sorting, Cycle Detection
13+
* Let's try to think of prerequisites pairs as a edge between two nodes in a graph.
14+
* Now this problem becomes simple, we just need to find out if there is any cycle in a graph or not.
15+
* If there is no cycle, then we can finish all the courses otherwise the answer is no.
16+
*/
17+
public class CourseSchedule {
18+
public static boolean canFinish(int numCourses, int[][] prerequisites) {
19+
// this is to keep track of visited nodes
20+
boolean[] vis = new boolean[numCourses];
21+
22+
// initialize adjacent graph
23+
List<List<Integer>> graph = new ArrayList<>();
24+
for(int i = 0; i < numCourses; i++) {
25+
graph.add(new ArrayList<>());
26+
}
27+
28+
for(int i = 0; i < prerequisites.length; i++) {
29+
graph.get(prerequisites[i][1]).add(prerequisites[i][0]);
30+
}
31+
32+
// set default ans to true
33+
// and we will only set it to false if and only if there is a cycle in the graph
34+
boolean ans = true;
35+
36+
// this is use to keep track of visited nodes in the current chain
37+
// Note: this is different from vis array
38+
Set<Integer> currentVisNodes = new HashSet<>();
39+
for(int i = 0; i < numCourses; i++) {
40+
// if we haven't visited this node, then let's try to find if there is a cycle or not
41+
if(!vis[i]) {
42+
ans &= dfs(graph, i, vis, currentVisNodes);
43+
currentVisNodes.clear();
44+
}
45+
}
46+
47+
return ans;
48+
}
49+
50+
private static boolean dfs(List<List<Integer>> graph, int currentNode, boolean[] vis, Set<Integer> currentVisNodes) {
51+
// set currentNode to visited
52+
vis[currentNode] = true;
53+
boolean possible = true;
54+
55+
// add this node to current chain
56+
currentVisNodes.add(currentNode);
57+
for(Integer nextNode: graph.get(currentNode)) {
58+
59+
// if we have found a node which we have already visited in the current chain then there is a loop
60+
if(currentVisNodes.contains(nextNode)) {
61+
possible = false;
62+
break;
63+
} else {
64+
// otherwise if we haven't visited next node then let's keep doing dfs recursively
65+
if(!vis[nextNode]) {
66+
possible &= dfs(graph, nextNode, vis, currentVisNodes);
67+
}
68+
}
69+
70+
}
71+
// in the end after exploring all the adjacent nodes of this node, remove the current node from the chain
72+
currentVisNodes.remove(Integer.valueOf(currentNode));
73+
return possible;
74+
}
75+
76+
public static void main(String[] args) throws IOException {
77+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
78+
int[] line = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::valueOf).toArray();
79+
int n = line[0];
80+
int m = line[1];
81+
82+
int[][] prerequisites = new int[m][2];
83+
for(int i = 0; i < m; i++) {
84+
line = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::valueOf).toArray();
85+
prerequisites[i][0] = line[0];
86+
prerequisites[i][1] = line[1];
87+
}
88+
89+
System.out.println(canFinish(n, prerequisites));
90+
}
91+
}

0 commit comments

Comments
 (0)