Leetcode 207. 课程表
拓扑排序题(其实本质是bfs),难点在于选取合适的数据结构并灵活运用。加了详细的注释,方便日后复习,也希望能帮到其他小伙伴,如有错误,欢迎指正!
Java实现:
class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
// 修每一门课之前所需修的课程数
int[] indegrees = new int[numCourses];
// 以每一门课为基础的课程列表
List<List<Integer>> out = new ArrayList<>();
// 一个队列,会将可修的课程加入q,因为修课程是先进先出,我们采用队列
Queue<Integer> q = new LinkedList<Integer>();
// 将二维列表补全
for (int i = 0; i < numCourses; i++){
out.add(new ArrayList<Integer>());
}
// 我们先要讲入度数组和out列表做一个预处理,利用题目给出的prerequisites,提取邻接关系,从而构造indegrees和out
for (int[] preq : prerequisites){
indegrees[preq[0]] ++;
out.get(preq[1]).add(preq[0]);
}
for (int j = 0; j < numCourses; j++){
// 第j门课入度为0,说明第j门课可以学了
if (indegrees[j] == 0) q.offer(j);
}
// 这里其实是广度优先搜索的思想,一层一层地遍历目前可修的课程,从而遍历所有课程
while (!q.isEmpty()){
// 接下来要学习这门课,将其弹出
int tmp = q.poll();
// 要修的课程总数-1
numCourses --;
// 将以这门课的为直接基础的课的入度-1,如果减1后课程的入度等于0,就说明这门课也可以学了,加入q中
for(int t : out.get(tmp)){
indegrees[t] --;
if (indegrees[t] == 0) q.offer(t);
}
}
// 因为每修一门课numCourses都会-1,因此经过bfs后,numCourses == 0就说明全部修完了,返回true,否则返回false
return numCourses == 0;
}
}