核心思想:dfs实现拓扑遍历
思路:
本题实则上就是根据给定的二维数组建立图然后判断是否存在拓扑排序。如果图存在环,那么课程安排失败。
class Solution {
boolean res = false; //有向图是否存在环
public boolean canFinish(int numCourses, int[][] prerequisites) {
//为有向图创建邻接表
List<List<Integer>> list = new ArrayList<>();
for(int i = 0; i < numCourses; i++){
list.add(new ArrayList<Integer>());
}
//每一行代表,对应以i课程为基础课程的后续课程(课程编码为[0,numCourses-1])
for(int[] p : prerequisites){
list.get(p[1]).add(p[0]);
}
//创建标记数组,表示某课程是否是被被访问
int[] sign = new int[numCourses];
//遍历每一个节点,查看是否出现环
for(int i = 0; i < numCourses; i++){
//课程未被访问且目前有向图无环
if(sign[i] == 0 && res == false){
dfs(list, sign, i);
}
}
//如果无环,则证明true
if(res){
return false;
}else{
return true;
}
}
public void dfs(List<List<Integer>> list, int[] sign, int i){
//表明当前正在访问i课程
sign[i] = 1;
//获取以i课程为基课程的所有后续课程
for(int e : list.get(i)){
//如果后续课程未被访问,则dfs
if(sign[e] == 0){
dfs(list, sign, e);
}else if(sign[e] == 1){ //再次访问到1,说明存在环
res = true;
return;
}
}
//上述循环全部执行完,未被return,则证明不存在环,则2表示i课程访问结束且无环
sign[i] = 2;
if(res){
return;
}
}
}