207. Course Schedule!
class Solution {
// mark the course if has been visited to avoid redundant calculation
boolean[] courseVisited;
// mark the path in dfs, if true, a circle is detected
boolean[] pathVisited;
boolean hasCircle;
public boolean canFinish(int numCourses, int[][] prerequisites) {
// 1. convert input to graph;
// 2. search if there is a circle in the graph;
// 3. backtrack and dfs
// 4. cache visited nodes
courseVisited = new boolean[numCourses];
pathVisited = new boolean[numCourses];
List<Integer>[] graph = buildGraph(numCourses, prerequisites);
for(int i=0; i<numCourses; i++){
detectCircle(i, graph);
}
return !hasCircle;
}
private void detectCircle(int course, List<Integer>[] graph){
// remember: first check if there is a circle before checking if the courseVisited!
if(pathVisited[course]){
hasCircle = true;
return;
}
if(hasCircle || courseVisited[course] || graph[course]==null) return;
courseVisited[course] = true;
pathVisited[course] = true;
List<Integer> requiredCourses = graph[course];
for(int requiredCourse: requiredCourses){
detectCircle(requiredCourse, graph);
}
pathVisited[course]=false;
}
private List<Integer>[] buildGraph(int numCourses, int[][] prerequisite){
List<Integer>[] graph = new LinkedList[numCourses];
for(int[] required: prerequisite){
int course = required[0];
int requiredCourse = required[1];
if(graph[course]==null){
graph[course]=new LinkedList();
}
graph[course].add(requiredCourse);
}
return graph;
}
}
Last updated
Was this helpful?