思路参考LeetCode
class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
//precourse[i]表示第i个课程有多少个入度,即该课程有多少个先修课
int[] precourse = new int[numCourses];
for (int[] pre:prerequisites){
//pre[0]和pre[1]的关系:
//想要学习课程pre[0],你需要先完成课程pre[1]
//当然,学习课程pre[0]的先修课程可能不止一门,因此需要遍历所有结果
int courseID = pre[0];
precourse[courseID]++;
}
//设置一个队列用于存放先修课为0的,即有向无环图(DAG)的顶点
LinkedList<Integer> linkedList = new LinkedList<Integer>();
for (int i=0;i<numCourses;i++){
if (precourse[i]==0){
//为0就表示该课程无须学习先修课程,可以直接学习
linkedList.add(i);
}
}
//一一取出队列中的值
while (linkedList.size()>0){
int course = linkedList.poll();
//每当去出一门课程时表示可以完成该门课程的学习
numCourses--;
//遍历先决条件
for (int[] pre:prerequisites){
//判断有哪些课程需要先完成课程号course才能进行学习的
if (pre[1]==course){
//还需判断该课程是否入度为1
//因为可能学习该课程需要完成两个或以上的课程才能学习
if (precourse[pre[0]]==1){
linkedList.add(pre[0]);
}else {
//如果不为1,那么将该课程学习需要的课程数减一
precourse[pre[0]]--;
}
}
}
}
//由于题目问的是是否可以完成所有课程的学习,只有当课程数量减到0
//才表示可以完成所有课程
return numCourses==0;
}
}