【每天学习一点算法 2026/05/22】课程表 II

每天学习一点算法 2026/05/22

题目:课程表 II

现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1。给你一个数组 prerequisites ,其中 prerequisitesi = ai, bi ,表示在选修课程 ai 前 必须 先选修 bi 。

例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示:0,1

返回你为了学完所有课程所安排的学习顺序。可能会有多个正确的顺序,你只要返回 任意一种 就可以了。如果不可能完成所有课程,返回 一个空数组 。

这题跟 课程表 的解法一样,只需要在回归过程往结果数组里面 push 课程即可。

typescript 复制代码
function canFinish(numCourses: number, prerequisites: number[][]): boolean {
  const status = new Array(numCourses).fill(0) // 用于记录课程状态:0 未搜索 1 搜索中 2 已搜索
  const graph: number[][] = Array.from({length:numCourses}, ()=>[]) // 邻接表,graph[i]表示学习课程 i 需要,先学习课程集合
  for(const [a,b] of prerequisites) graph[a].push(b) // 遍历 prerequisites 初始化邻接表
  
  const res = [] // 课程学习顺序
  
  // 辅助函数,用于深度优先遍历从某课程开始向上搜索它依赖课程
  function helper (course: number) {
    if (status[course] === 1) return false // 如果课程处于搜索中状态返回false
    if (status[course] === 2) return true // 如果课程处于已搜索状态返回true
    status[course] = 1 // 修改当前课程为搜索中状态
    for (const pre of graph[course]) {
      // 递归搜索当前课程所有前置课程
      if (!helper(pre)) return false // 前置课程中有处于搜索中的会得到false, 直接返回false
    }
    // 回归到此说明此课程可以完成学习,标记为已搜索,并返回true
    status[course] = 2
    res.push(course) // 我们递归的边界是最先需要学习的课程,所以回归时直接 push 就是学习顺序
    return true
  }
  // 主循环,遍历所有课程,进行搜索
  for (let i = 0; i < numCourses; i++) {
    if (status[i] === 2) {
      // 已搜索过的课程直接跳过
      continue
    }
    if (!helper(i)) {
      // 当前课程建立有向图存在环,无法完成,直接返回空数组
      return []
    }
  }
  // 遍历完成返回学习顺序数组
  return res
};

题目来源:力扣(LeetCode)

相关推荐
卷福同学10 小时前
不用服务器,不用配环境,我10分钟上线了一个AI Agent
人工智能·后端·算法
至乐活着12 小时前
深入解析跳表SkipList:原理、实现与性能优化实战
数据结构·算法·跳表·skiplist·java实现
r_oo_ki_e_13 小时前
Java Map 集合学习笔记
java·笔记·学习
Jerry13 小时前
LeetCode 383. 赎金信
算法
ai产品老杨13 小时前
H264 H265视频分析常见问题和排查清单
人工智能·算法·音视频
Jerry14 小时前
LeetCode 454. 四数相加 II
算法
笨鸟先飞的橘猫14 小时前
skynet——sharetable学习
学习·skynet
liuyicenysabel14 小时前
大模型学习笔记 · 第八篇 · 进阶:偏好对齐与多卡训练
人工智能·笔记·学习
可编程芯片开发14 小时前
基于CPS-SPWM链式STATCOM系统在电压不平衡环境下控制策略的simulink建模与仿真
算法
Jerry15 小时前
LeetCode 202. 快乐数
算法