构造了图结构,在外部用了dfs,最后计算hasCycle
public class Solution {
boolean hasCycle = false;
Set set = new HashSet<Integer>();
class DGraph{
int n ;
private boolean[] marked;
private boolean[] onstack;
Set<Integer>[] DNodeBag;
public DGraph(int n) {
this.n = n;
DNodeBag = new HashSet[n];
marked =new boolean[n];
onstack = new boolean[n];
}
public void addEdge(int v,int n){
DNodeBag[v].add(n);
}
}
public boolean canFinish(int numCourses, int[][] prerequisites) {
DGraph dGraph = new DGraph(numCourses);
for (int i = 0;i<numCourses;i++){
dGraph.DNodeBag[i] = new HashSet<Integer>();
}
for (int i=0; i<prerequisites.length;i++){
for (int j=0;j<prerequisites[i].length-1;j++){
dGraph.addEdge(prerequisites[i][j],prerequisites[i][j+1]);
}
}
findCycle(dGraph);
return !hasCycle;
}
private void findCycle(DGraph dGraph) {
for (int i=0;i<dGraph.n;i++){
if(hasCycle) return;
if(set.contains(i))continue;
dfs(dGraph,i);
dGraph.onstack = new boolean[dGraph.n];
dGraph.marked = new boolean[dGraph.n];
}
}
//这里计算hasCycle,其中又有个set保存之前遍历过的不是环的点,以后如果有点经过,可以直接判断这条路不是环。onstack数组又来保存着一条路之前遍历过点(可能有很多路)。
private void dfs(DGraph dGraph,int v){
if (hasCycle){
return;
}
if (dGraph.onstack[v]){
hasCycle = true;
return;
}
if (dGraph.marked[v]){
return;
}
if (hasCycle){
return;
}
dGraph.marked[v] = true;
for (int w:dGraph.DNodeBag[v]){
set.add(w);
dGraph.onstack[v] = true;
dfs(dGraph,w);
dGraph.onstack[v] = false;
}
}
}