题目描述
分析
能否完成课程实际上是看是否存在没法学习的课程
因此本题我的解题思路是将所有的课程从没有依赖的开始,寻找他们的关系
形成一个拓扑结构,最终检查是否有剩余课程
算法
拓扑排序
过程
统计
统计每个节点的入度,将结构放到 indeg 数组
统计每个节点指向的节点,这是为了拓扑排序,将结果放到 g
遍历 indeg 数组,将没有入度的节点放入队列 q,作为查找的开始节点
查找
利用一个基数器 cnt 统计已上课程数量
从 q 不断弹出元素,每次弹出后:
- 计数器++
- 让它指向的节点入度--
- 如果减小入度后发现有入度为 0 的,放入
q
检查
看上完的课程是否等于课程总数
代码
/**
* @param {number} numCourses
* @param {number[][]} prerequisites
* @return {boolean}
*/
var canFinish = function (numCourses, prerequisites) {
// if circle detected, return false
// use directed circle
const indeg = new Array(numCourses).fill(0)
const q = [] // topology sequence,push all nodes with 0 indeg to arr
const g = new Array(numCourses).fill(0).map(() => new Array()) // a set indicates which nodes a node points to
for (const x of prerequisites) {
// calc indeg & direction
// x[1] -> x[0]
indeg[x[0]]++ // indeg ++
g[x[1]].push(x[0])
}
// push all nodes with 0 indeg to q
for (let i = 0; i < numCourses; i++) {
if (indeg[i] === 0) q.push(i)
}
// processs each node
// each node we have put into q, is a node in topology sequence
let cnt = 0 // nodes num in topology sequence
while (q.length) {
let ind = q.shift()
cnt++
for (const to of g[ind]) {
indeg[to] -= 1
if (indeg[to] === 0) q.push(to)
}
}
return cnt === numCourses
}