题目链接
https://leetcode.com/problems/course-schedule/
题意
一共有 numCourses 门课程,一些课程必须学完前置课程才能够学习,问是否能学完所有课程。比如:course0 的前置课程是 course1,而 course1 的前置课程是 course0,则无法学完。
思路
这道题就是给出了一个有向图判断是否成环。这里需要对一个有向无环图进行拓扑排序,主要的步骤为:
- 找出出度为 0 的点(即没有前置课程的课)
- 在图中删除该节点,及以它为目的地的边(相当于已学习了这门课程)
- 重复 1.2 步骤,直到不存在出度为 0 的点
此时,如果所有点都被删除则可以学完。
代码(JavaScript)
/**
* @param {number} numCourses
* @param {number[][]} prerequisites
* @return {boolean}
*/
var canFinish = function(numCourses, prerequisites) {
let map = new Array(numCourses); // 图
let degree = new Array(numCourses).fill(0); // 各点出度
for (let i = 0; i < numCourses; i++) {
map[i] = new Array(numCourses).fill(0);
}
for (let pre of prerequisites) {
map[pre[0]][pre[1]] = 1;
degree[pre[0]]++;
}
let q = [];
// 找出所有出度为 0 的点
for (let i = 0; i < numCourses; i++) {
if (degree[i] === 0) {
q.push(i);
}
}
let cnt = 0;
while(q.length) {
let h = q.shift();
for (let i = 0; i < numCourses; i++) {
if (map[i][h] === 1) {
degree[i]--;
if (degree[i] === 0) {
q.push(i);
}
}
}
cnt++;
}
return cnt === numCourses;
};