Copy class Solution {
class Course {
int courseNumber;
Set<Course> prevCourse;
Set<Course> nextCourse;
State state;
// = State.UNVISITED;
public Course(int course) {
this.courseNumber = course;
this.prevCourse = new HashSet<>();
this.nextCourse = new HashSet<>();
this.state = State.UNVISITED;
}
@Override
public int hashCode(){
int hashCode = this.courseNumber * 31 + 31;
return hashCode;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (this.getClass() != obj.getClass()) {
return false;
}
Course that = (Course) obj;
return this.courseNumber == that.courseNumber;
}
}
class ReturnType{
boolean isCycle = true;
int count;
public ReturnType(boolean isCycle, int count) {
this.isCycle = isCycle;
this.count = count;
}
}
public boolean canFinish(int numCourses, int[][] prerequisites) {
// sanity check
// build graph
Map<Integer, Course> graph = buildGraph(numCourses, prerequisites);
// Set<Course> init = buildInit(graph);
int globalCount = 0;
for (int courseNumber: graph.keySet()) {
Course init = graph.get(courseNumber);
if (init.prevCourse.isEmpty()){
ReturnType curResult = dfs(init, graph);
// System.out.println(curResult.count);
if (curResult.isCycle == true) {
return false;
}
globalCount += curResult.count;
}
}
return globalCount == numCourses;
}
private ReturnType dfs(Course init, Map<Integer, Course> graph) {
if (init.state == State.VISITED) {
return new ReturnType(false, 0);
}
if (init.state == State.VISITING) { // 注意这两个的顺序,如果你不是exclusive的状态
return new ReturnType(true, 0);
}
init.state = State.VISITING;
int count = 1;
for (Course next: init.nextCourse) {
ReturnType nextResult = dfs(next, graph);
// System.out.println(nextResult.count);
// System.out.println(nextResult.isCycle);
if (nextResult.isCycle == true) {
return new ReturnType(true, 0);
}
count += nextResult.count;
}
init.state = State.VISITED; // 注意,这里是先标visiting,然后再标visited,否则会出错。。。
// System.out.println(count);
return new ReturnType(false, count);
}
private Map<Integer, Course> buildGraph(int numCourses, int[][] prerequisites) {
Map<Integer, Course> graph = new HashMap<>();
for (int i = 0; i < numCourses; i++) {
graph.put(i, new Course(i));
}
for (int[] depe: prerequisites) {
int nextCourse = depe[0];
int prevCourse = depe[1];
Course next = graph.get(nextCourse);
Course prev = graph.get(prevCourse);
next.prevCourse.add(prev);
// System.out.println(next.prevCourse);
prev.nextCourse.add(next);
// System.out.println(prev.nextCourse);
}
return graph;
}
private enum State {
VISITED,
VISITING,
UNVISITED,
}
}