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

Leetcode210. 课程表 II

Every day a Leetcode

题目来源:210. 课程表 II

解法1:

什么是拓扑排序?

在这里插入图片描述

我们考虑拓扑排序中最前面的节点,该节点一定不会有任何入边,也就是它没有任何的先修课程要求。当我们将一个节点加入答案中后,我们就可以移除它的所有出边,代表着它的相邻节点少了一门先修课程的要求。如果某个相邻节点变成了「没有任何入边的节点」,那么就代表着这门课可以开始学习了。按照这样的流程,我们不断地将没有入边的节点加入答案,直到答案中包含所有的节点(得到了一种拓扑排序)或者不存在没有入边的节点(图中包含环)。

上面的想法类似于广度优先搜索,因此我们可以将广度优先搜索的流程与拓扑排序的求解联系起来。

算法:

在这里插入图片描述

代码:

/** @lc app=leetcode.cn id=210 lang=cpp** [210] 课程表 II*/// @lc code=start// 拓扑排序(广度优先搜索)class Solution
{
public:vector<int> findOrder(int numCourses, vector<vector<int>> &prerequisites){// 邻接矩阵vector<vector<int>> graph(numCourses, vector<int>());// 入度数组vector<int> inDegree(numCourses, 0);vector<int> ans;// 初始化邻接矩阵和入度数组for (vector<int> &p : prerequisites){graph[p[1]].push_back(p[0]);inDegree[p[0]]++;}queue<int> q;// 把入度为 0 的节点(即没有前置课程要求)放在队列中for (int i = 0; i < inDegree.size(); i++)if (inDegree[i] == 0)q.push(i);while (!q.empty()){// 每次从队列中获得节点,我们将该节点放在排序的末尾,// 并且把它指向的课程的入度各减 1int u = q.front();q.pop();ans.push_back(u);for (auto &v : graph[u]){inDegree[v]--;// 有课程的所有前置必修课都已修完(即入度为 0),// 我们把这个节点加入队列中if (inDegree[v] == 0)q.push(v);}}// 当队列的节点都被处理完时,说明所有的节点都已排好序,// 或因图中存在循环而无法上完所有课程for (int &in : inDegree){// 不可能完成所有课程if (in != 0)return {};}return ans;}
};
// @lc code=end

结果:

在这里插入图片描述

复杂度分析:

时间复杂度: O(n+m),其中 n 为课程数,m 为先修课程的要求数。这其实就是对图进行广度优先搜索的时间复杂度。

空间复杂度: O(n+m)。题目中是以列表形式给出的先修课程关系,为了对图进行广度优先搜索,我们需要存储成邻接表的形式,空间复杂度为 O(n+m)。在广度优先搜索的过程中,我们需要最多 O(n) 的队列空间(迭代)进行广度优先搜索,并且还需要若干个 O(n) 的空间存储节点入度、最终答案等。

相关文章:

  • 大语言模型LLM推理加速:LangChain与ChatGLM3-6B的推理加速技术(LLM系列11)
  • 【Redis】高级特性 - 有序集合
  • 【mysql 数据库事务】开启事务操作数据库,写入失败后,不回滚,会有问题么? 这里隐藏着大坑,复试,面试时可以镇住面试老师!!!!
  • 【pytorch】函数记录
  • 【MySQL】学习多表查询和笛卡尔积 - 副本
  • PureFlash v1.9.1特性介绍
  • 【Android 从入门到出门】第二章:使用声明式UI创建屏幕并探索组合原则
  • 【QT+QGIS跨平台编译】之六十三:【QGIS_CORE跨平台编译】—【错误处理:未定义的类QgsMapLayer - QgsMapLayerModel】
  • 《Vite 基础知识》关于 .mjs .cjs 文件引出 NodeJS 对JS模块加载的思考(CommonJS 和 ESM)
  • 云上攻防-云原生篇Docker安全权限环境检测容器逃逸特权模式危险挂载
  • 零基础怎么学编程,从哪里入手,分享中文编程工具及教程,编程轻松学
  • ABAP - SALV教程11 红黄绿灯
  • Unity 切换场景
  • 微信小程序云开发教程——墨刀原型工具入门(添加交互事件)
  • 设计一基于Text generation web UI的语言模型部署与远程访问的方案​
  • 77. Combinations
  • Django 博客开发教程 8 - 博客文章详情页
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • mockjs让前端开发独立于后端
  • PV统计优化设计
  • React-生命周期杂记
  • Redis中的lru算法实现
  • Spring声明式事务管理之一:五大属性分析
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 好的网址,关于.net 4.0 ,vs 2010
  • 前端面试总结(at, md)
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • 使用API自动生成工具优化前端工作流
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 无服务器化是企业 IT 架构的未来吗?
  • 小李飞刀:SQL题目刷起来!
  •  一套莫尔斯电报听写、翻译系统
  • Semaphore
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • (04)odoo视图操作
  • (arch)linux 转换文件编码格式
  • (C++)栈的链式存储结构(出栈、入栈、判空、遍历、销毁)(数据结构与算法)
  • (三)uboot源码分析
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • (一)为什么要选择C++
  • (正则)提取页面里的img标签
  • (转载)深入super,看Python如何解决钻石继承难题
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • .Net下的签名与混淆
  • /dev/sda2 is mounted; will not make a filesystem here!
  • /var/spool/postfix/maildrop 下有大量文件
  • [ 云计算 | AWS 实践 ] 基于 Amazon S3 协议搭建个人云存储服务
  • [<死锁专题>]
  • [CSS]CSS 的背景
  • [dts]Device Tree机制