思路:
广度优先遍历,是拓扑排序,主要是不能出现环
利用一个入度表
代码:
class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
if(numCourses==0) return false;
//这里若数组为空,返回的是true而不是false
if(prerequisites.length==0) return true;
//这里不能写List,而是写成LinedList才能通过编译
LinkedList<Integer> queue=new LinkedList<>();
int[] inDegree=new int[numCourses];
//遍历所有节点,有入度的加度
for(int[] p:prerequisites){
inDegree[p[0]]++;
}
//遍历所有课程
for(int i=0;i<numCourses;i++){
if(inDegree[i]==0){
queue.addLast(i);
}
}
List<Integer> res=new ArrayList<>();
while(!queue.isEmpty()){
//这里出来的是Integer而不是int
Integer num=queue.removeFirst();
//相当于把所有值都存到res里
res.add(num);
//遍历所有临边
for(int[] p:prerequisites){
if(p[1]==num){
inDegree[p[0]]--;
if(inDegree[p[0]]==0){
queue.addLast(p[0]);
}
}
}
}
return res.size()==numCourses;
}
}
分解:
1)numCourses==0返回false,但数组为空prerequisites.length==0,则返回true
2)先遍历一遍数组,把每一组的第一个元素的入度自增,其余默认为0
3)把入度为0的加入到队列中,再逐个出队,通过这个数字找到临边,减去临边的入度,如果临边的入度这时为0,就加入队列。
注意:每次出队后,都要把元素加入到res中,最后比较res的长度与课程数是否相同(能加入队列说明入度都为0)