判断图是否有环,没有环才能完成作业。
如果有环,循环依赖,不可完成。例如:1需要0,0需要1,死结。
//单独做成员变量,不用再放在函数参数传递。
boolean[] visited;
boolean[] path;
boolean hasCycle = false;
public boolean canFinish(int numCourses, int[][] prerequisites) {
visited = new boolean[numCourses];
path = new boolean[numCourses];
List<Integer>[] list = createGraph(numCourses, prerequisites);
//可能存在独立的节点,所有这层控制每个节点遍历。
for(int i = 0; i < numCourses; i++){
//注意这里传递的是i ,每个节点都要遍历
dfs(list, i);
}
//有环不能完成作业
return !hasCycle;
}
List<Integer>[] createGraph(int numCourses, int[][] prerequisites){
List<Integer>[] list = new LinkedList[numCourses];
for(int i = 0; i < numCourses; i++){
list[i] = new LinkedList<>();
}
for(int[] tmp : prerequisites){
int wantstudy = tmp[0];
int needstudy = tmp[1];
// 这种图是从学了的,指向下一个可以学的课。
list[needstudy].add(wantstudy);
}
return list;
}
//这道题主要是判断是否有环
void dfs(List<Integer>[] list, int node){
if(path[node]){
hasCycle = true;
}
//访问过,或者有环就返回,这个题主要就是找环。
if(visited[node] || hasCycle){
return;
}
visited[node] = true;
//path记录当前正在走的路径的节点。
path[node] = true;
for(int next : list[node]){
dfs(list, next);
}
path[node] = false;
}