课程表

168 阅读1分钟

题目描述

leetcode-cn.com/problems/co…

分析

能否完成课程实际上是看是否存在没法学习的课程

因此本题我的解题思路是将所有的课程从没有依赖的开始,寻找他们的关系

形成一个拓扑结构,最终检查是否有剩余课程

算法

拓扑排序

过程

统计

统计每个节点的入度,将结构放到 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
}