当前位置: 首页 > news >正文

【LeetCode 第207题】

LeetCode 207

  • LeetCode 207 课程表(拓扑排序 + 邻接表实现)题解
    • 题目描述
    • 二、核心思路:拓扑排序(Kahn算法)
      • 步骤:
    • 三、代码实现解析(重点)
      • 1. 邻接表结构
      • 加边函数
      • 2. 建图 + 入度统计
      • 3. 初始化队列(入度为 0)
      • 4. 拓扑排序过程
      • 5. 判断是否有环
    • 四、复杂度分析
    • 五、一些关键理解点
      • 1️⃣ 为什么入度为 0 可以学?
      • 2️⃣ 为什么能检测环?
    • 六、总结
    • 七、推荐优化(可写进进阶部分)

LeetCode 207 课程表(拓扑排序 + 邻接表实现)题解

题目描述

题目理解
这道题本质是在问:

给你一堆课程依赖关系,能不能把所有课程都学完?

比如:

  • [1, 0]表示:学 1 之前必须先学 0
  • 也就是:0 → 1

问题就变成:

👉这个有向图中是否存在环?

  • 有环 ❌ → 一定学不完(死循环)
  • 无环 ✅ → 可以学完(存在拓扑序)

二、核心思路:拓扑排序(Kahn算法)

我们用入度 + BFS(或栈模拟)来做:

步骤:

  1. 建图(邻接表)

  2. 统计每个点的入度

  3. 把所有入度为 0 的点加入队列

  4. 每次取一个点:

    • 删除它(模拟学完)
    • 它指向的点入度减 1
    • 如果某个点入度变成 0 → 入队
  5. 最后看:

    • 能不能把所有点都删掉

三、代码实现解析(重点)

手写邻接表 + 拓扑排序,ACM 风格 👍

1. 邻接表结构

inth[N],e[N],ne[N],idx;

含义:

数组作用
h每个点的链表头
e边的终点
ne下一条边
idx当前边编号

加边函数

voidadd(inta,intb){e[idx]=b;ne[idx]=h[a];h[a]=idx++;}

表示:
👉 从a → b


2. 建图 + 入度统计

for(auto&edge:prerequisites){intai=edge[0];intbi=edge[1];add(bi,ai);// bi → aiin[ai]++;}

解释:

  • [ai, bi]表示:bi → ai

  • 所以:

    • 加边bi → ai
    • ai入度 +1

3. 初始化队列(入度为 0)

for(inti=0;i<numCourses;i++){if(in[i]==0){q.push_back(i);s.insert(i);st[i]=true;}}

这里做了三件事:

  • q:模拟队列(你用 vector 当栈用)
  • s:记录访问过的节点
  • st:防止重复入队

4. 拓扑排序过程

while(!q.empty()){intu=q.back();q.pop_back();for(inti=h[u];i!=-1;i=ne[i]){intv=e[i];in[v]--;if(in[v]==0&&!st[v]){st[v]=true;s.insert(v);q.push_back(v);}}}

流程:

  1. 取一个入度为 0 的点u
  2. 遍历它的所有邻居v
  3. 入度--
  4. 如果变成 0 → 加入队列

5. 判断是否有环

returns.size()==numCourses;

解释:

  • 如果所有点都被“删除”(拓扑排序成功)
    s.size() == n
  • 否则说明:
    → 有环 ❌

四、复杂度分析

  • 时间复杂度:
    👉O(n + m)
  • 空间复杂度:
    👉O(n + m)

其中:

  • n:课程数
  • m:依赖关系数

五、一些关键理解点

1️⃣ 为什么入度为 0 可以学?

因为:

👉 没有任何课程依赖它


2️⃣ 为什么能检测环?

如果有环:

0 → 1 → 2 → 0

那每个点入度都 ≥ 1
👉永远没有入度为 0 的点

➡️ 拓扑排序无法开始 / 中途卡住


六、总结

一句话总结这题:

判断有向图是否有环 → 用拓扑排序

七、推荐优化(可写进进阶部分)

其实可以把这部分简化:

unordered_set<int>s;boolst[N];

👉 完全可以换成:

intcnt=0;

每处理一个点:

cnt++;

最后:

returncnt==numCourses;

更轻量、更高效 👍

http://www.jsqmd.com/news/916146/

相关文章:

  • 别再死记硬背了!用Kettle调用存储过程的两种方法,附上我踩过的坑
  • DS4Windows终极配置指南:7步实现游戏手柄完美映射
  • DIY高扭矩机器人关节执行器:BLDC电机+FOC控制+行星减速箱全解析
  • 3步完成QMC音频解码:一键解锁加密音乐,实现跨平台播放自由
  • 麦峰整装全渠道联系方式汇总 青岛装修咨询一键直达 - 商业新知
  • 分布式相控阵技术在卫星通信中的应用与优化
  • 坐席辅助智能体:搞定客服管理难题,让团队效率与口碑双向突围!
  • 一文看懂企业网盘安全真相:为什么“企业级同步盘”比通用网盘更重要
  • 2026年华为OD机试(A卷,100分)- 幻方修复(Java JS Python)带详细解释和源码
  • 跨平台模组下载终极指南:无需Steam轻松访问创意工坊的完整解决方案
  • QMC音频解码器:3分钟解锁加密音乐,实现跨平台播放自由
  • 终极指南:如何用Wand-Enhancer解锁WeMod完整功能体验
  • 2026年昆明代理记账与云南工商变更全生命周期财税服务综合解读:避坑指南与靠谱机构推荐 - 企业名录优选推荐
  • ESP32与Firebase构建足球场智能灌溉系统:从传感器到云端全链路实践
  • 基于本体语义与对象特征的非结构化信息搜索解析方案【附代码】
  • 3步搞定多平台直播弹幕采集:零基础快速上手BarrageGrab终极指南
  • 在Corstone-1000的Yocto构建系统中集成helloworld应用
  • 2026新疆定制游与政企接待选择:旅行社深度横评避坑指南 - 优质企业观察收录
  • 基于OpenCV与Haar级联分类器的实时人脸检测实战教程
  • 每日热门skill:你以为当AI Agent有了「记忆超能力」就够了吗?这个Skill让机器学会「关系思維」
  • 别被忽悠了!2026亲测好用的AI论文平台|实测避坑硬核版
  • SecureCRT 9.1.0不止于连接:挖掘你可能不知道的5个高效技巧与脚本自动化
  • QMC-Decoder终极指南:三步搞定QQ音乐加密文件转换
  • 太原黄金上门回收平台推荐2026 - 黄金回收
  • 2026年昆明代理记账与工商变更综合评测:云南企业财税服务选型避坑全手册 - 企业名录优选推荐
  • Merkle树原理与区块链高效验证技术解析
  • 从相亲匹配到项目派单:匈牙利算法在生活与工作中的3个真实应用
  • 中国传媒大学考研辅导班强烈推荐【独峰考研】全解析 - michalwang
  • 中国民航大学考研辅导班强烈推荐【独峰考研】全解析 - michalwang
  • 2026 哈尔滨钻石回收便民实用指南,闲置变现轻松省心 - 薛定谔的梨花猫