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

LeetCode 热题 100 | 图论(二)

目录

1  基础知识

1.1  什么是拓扑排序

1.2  如何进行拓扑排序

1.3  拓扑排序举例

2  207. 课程表

3  210. 课程表 II


菜鸟做题,语言是 C++

1  基础知识

1.1  什么是拓扑排序

含义:根据节点之间的依赖关系来生成一个有序的序列。

应用:

  • 在项目管理中,按照任务之间的的依赖关系来安排执行顺序。
  • 在编译原理中,按照编译单元的依赖关系来确定编译单元的生成顺序。
  • 在程序设计中,按照模块之间的依赖关系来确定模块的加载和执行顺序。

突然想起来好像在操作系统原理里学过!

1.2  如何进行拓扑排序

排序步骤:

  1. 选择入度为 0 的节点加入到排序结果中,并从图中移除该节点以及它的所有出边;
  2. 重复步骤 1,每次都选择入度为 0 的节点加入到排序结果中,并更新图中剩余节点的入度;
  3. 重复步骤 1 和 2,直到所有的节点都被加入到排序结果中,或者不再存在入度为 0 的节点。

名词解释:

  • → 节点  属于节点的 入边
  • 节点 →  属于节点的 出边

如果图中不再存在入度为 0 的节点,且并非所有的节点都被加入到排序结果中,那么说明原图中存在环。综上,拓扑排序的主要功能是帮助安排顺序,顺带帮助检测图中有没有环。

1.3  拓扑排序举例

下图描述了一个拓扑排序过程。

① 入度为 0 的节点有 B、D,我们任意选择 B,并删除它的出边:

② 入度为 0 的节点有 A、D,我们任意选择 A,并删除它的出边;更新后,入度为 0 的节点有 C、D,我们任意选择 C,并删除它的出边:

③ 入度为 0 的节点有 D,我们选择 D,并删除它的出边;更新后,入度为 0 的节点有 F,我们选择 F,并删除它的出边:

以此类推,不再赘述。通过 “任意选择” 一词可以看出,拓扑排序的结果不止一种。

2  207. 课程表

感觉解题方法和拓扑排序关系不大,更多的是从题意出发;想了很久要怎么才能把思路表述清楚,最终认为还是看代码来得快 TT

解题思路:假设有先修课程对 [0,1] 和 [0,2]

  • 初始化:获取每门课程的先修课程数组,比如:0 对应 [1,2]
  • 初始化:设置记录访问状态的数组,并将访问状态全部置为 0
  • 循环:访问每门课程,判断它的先修课程是否已经被全部修完
  • 如果它的先修课程未被全部修完,则表明无法完成所有课程的学习

访问状态:

  • visited[course] = 0:该门课程还未被学习
  • visited[course] = 1:该门课程正在被学习
  • visited[course] = 2:该门课程已经被学习

针对 “该门课程正在被学习” 的说法,需要说明的是,这是算法题而不是现实生活!如果一门课正在被学习,不是代表学习它需要一段时间,而是代表它的先修课程不可能被修完,导致我们永远学不了它。

class Solution {
public:vector<int> visited;vector<vector<int>> mustFinish;bool possible = true;void helper(int course) {// 指明该门课程正在被学习visited[course] = 1;// 判断其先修课程是否已被修完for (auto & preCourse : mustFinish[course]) {// 递归访问未被学习的先修课程if (visited[preCourse] == 0) {helper(preCourse);if (!possible) return;// 先修课程正在被学习(因为卡住了)} else if (visited[preCourse] == 1) {possible = false;return;}}// 指明该门课程已经被学习visited[course] = 2;}bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {visited.resize(numCourses);mustFinish.resize(numCourses);// 获取每门课程的先修课程数组for (auto & p : prerequisites) {mustFinish[p[0]].push_back(p[1]);}// 循环访问每门课程for (int i = 0; i < numCourses && possible; ++i) {helper(i);}return possible;}
};

3  210. 课程表 II

在  207. 课程表  的基础上,增加一个数据结构来存储课程顺序即可。

唯一区别在于:

for (int i = 0; i < numCourses && possible && !visited[i]; ++i)

新增条件 !visited[i],不允许已经被访问过的课程再被访问,避免了课程重复被学习。

class Solution {
public:vector<int> visited;vector<vector<int>> mustFinish;bool possible = true;vector<int> ans;void helper(int course) {visited[course] = 1;for (auto & preCourse : mustFinish[course]) {if (visited[preCourse] == 0) {helper(preCourse);if (!possible) return;} else if (visited[preCourse] == 1) {possible = false;return;}}visited[course] = 2;ans.push_back(course);}vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {visited.resize(numCourses);mustFinish.resize(numCourses);for (auto & p : prerequisites) {mustFinish[p[0]].push_back(p[1]);}for (int i = 0; i < numCourses && possible && !visited[i]; ++i) {helper(i);}if (possible) return ans;return {};}
};

相关文章:

  • 【粉丝福利】一本书讲透ChatGPT,实现从理论到实践的跨越!大模型技术工程师必读
  • 线性代数笔记11--矩阵空间、秩1矩阵
  • 数据库-第四/五章 数据库安全性和完整性【期末复习|考研复习】
  • [Vulnhub]靶场 Web Machine(N7)
  • 【CSP试题回顾】202209-2-何以包邮?
  • 各中间件性能、优缺点对比
  • Android使用OpenGL和FreeType绘制文字
  • 【MATLAB】语音信号识别与处理:卷积滑动平均滤波算法去噪及谱相减算法呈现频谱
  • 第七篇:人工智能与机器学习技术VS量测(Measurement)- 我为什么要翻译介绍美国人工智能科技巨头IAB公司 - 它是如何赋能数字化营销生态的?
  • 前端工具网站合集(持续更新)
  • 数学建模介绍
  • 探索云原生世界:Serverless 技术的崛起与应用
  • Centos 9 安装 k8s
  • python基础使用之“__name__==‘__main__‘”作用
  • 大数据开发-Hadoop分布式集群搭建
  • Markdown 语法简单说明
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • vue学习系列(二)vue-cli
  • 大快搜索数据爬虫技术实例安装教学篇
  • 悄悄地说一个bug
  • 区块链将重新定义世界
  • 人脸识别最新开发经验demo
  • 深度学习中的信息论知识详解
  • 使用 @font-face
  • 通过npm或yarn自动生成vue组件
  • #define MODIFY_REG(REG, CLEARMASK, SETMASK)
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • $L^p$ 调和函数恒为零
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • .NET CF命令行调试器MDbg入门(一)
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .NET Core 将实体类转换为 SQL(ORM 映射)
  • .net core使用RPC方式进行高效的HTTP服务访问
  • .NET 将混合了多个不同平台(Windows Mac Linux)的文件 目录的路径格式化成同一个平台下的路径
  • .Net多线程总结
  • .net最好用的JSON类Newtonsoft.Json获取多级数据SelectToken
  • [20150707]外部表与rowid.txt
  • [ARC066F]Contest with Drinks Hard
  • [ASP.NET MVC]如何定制Numeric属性/字段验证消息
  • [hive] sql中distinct的用法和注意事项
  • [IOI2018] werewolf 狼人
  • [Linux](16)网络编程:网络概述,网络基本原理,套接字,UDP,TCP,并发服务器编程,守护(精灵)进程
  • [msg_msg] corCTF2021 -- fire_of_salvation
  • [nlp] tokenizer
  • [node]Node.js 模块系统
  • [NOI2014]购票
  • [one_demo_15]模拟交通灯管理系统
  • [one_demo_3]漩涡递增矩阵
  • [PHP源码阅读]empty和isset函数
  • [THUWC 2017]在美妙的数学王国中畅游
  • [Unity独立/合作开发]实现背包系统中物品的拾取拖拽掉落还有换位置