【BFS 解决拓扑排序】课程表
文章目录题目解析算法原理建图入度数组代码实现题目链接207. 课程表题目解析拓扑排序Topological sorting要解决的问题是如何给一个有向无环图的所有节点排序。有向无环图Directed Acyclic Graph, 缩写 DAG是一种边有方向且没有环形结构的图结构。拓扑排序的起始点是顶点入度为0的节点将顶点排序完毕后从该顶点发出的有向边全部会被删除这使得被指向的节点的入度数会减1当入度数为0时这个节点就成为新了的顶点然后下一轮从该顶点开始排序以此重复直到没有顶点为止。入度表示指向某节点的有向边数量出度表示从该节点发出的有向边数量构造拓扑序列步骤从图中选择一个入度为零的点输出该顶点从图中删除此顶点及其所有的出边重复上面两步直到所有顶点都输出拓扑排序完成或者图中不存在入度为零的点此时说明图是有环图拓扑排序无法完成陷入死锁。例子做一道青椒炒肉的过程图如下按照流程图中的顺序一步一步做出来这道菜的过程就相当于是拓扑排序的过程。拓扑排序的目标是将所有节点排序可能出现多个不同的排序结果买菜 — 准备厨具 — 洗菜 — 腌肉 — 切菜 — 炒菜 — 装盘准备厨具 — 买菜 — 洗菜 — 腌肉 — 切菜 — 炒菜 — 装盘准备厨具 — 买菜 — 洗菜 — 切菜 — 腌肉 — 炒菜 — 装盘准备厨具 — 腌肉 — 买菜 — 洗菜 — 切菜 — 炒菜 — 装盘如何实现拓扑排序借助队列一次多源 BFS 即可先将所有入度为0的节点放入队列层序遍历先拿出队首元素并添加到结果中然后将从该队首元素发出的边全部删去再判断与这些边相连的节点的入度减一之后的值是否为0若为0就再加入队列中题目给出一个numCourses表示本学期要修读的课程数记作0-numCourses-1。在选修某些课程之前需要一些先修课程。先修课程由数组prerequisites给出其中prerequisites[i] [a, b]表示如果要学习课程a则必须先学习课程b。我们需要判断能否完成所有课程的学习。例1numCourses 2, prerequisites [[1,0]]prerequisites[0] [1, 0]表示要学习课程1必须先学习课程0而总课程数numCourses 2这两门课程可能就是课程1和课程0因此可以先学习课程0再学习课程1是可能完成所有课程的学习的因此返回true。例2numCourses 5, prerequisites [[1,0], [2,0], [3,0], [3,1], [3,2], [4,3]]学习课程的顺序可以是0 — 1 — 2 — 3 — 4因此是可以完成所有课程的学习的返回true。算法原理例numCourses 5, prerequisites [[1,0], [2,0], [3,0], [3,1], [3,2], [4,3]]根据题目所给可以画出我们需要判断的 ”能否完成所有课程的学习“ 其实就是判断有向无环图中是否存在环—— 即能否进行拓扑排序。因此我们可以用拓扑排序来解决本题。构造拓扑序列步骤从图中选择一个入度为零的点输出该顶点从图中删除此顶点及其所有的出边重复上面两步直到所有顶点都输出拓扑排序完成或者图中不存在入度为零的点此时说明图是有环图拓扑排序无法完成陷入死锁。建图在构造拓扑序列之前首先要根据题目抽象出图结构。我们用邻接表来表示图的结构代码实现有两种方式对于字符串类型的数据我们通常用哈希表Map String, List String edges作为邻接表来映射 ”节点相连的节点列表“。对于整数类型的数据我们通常用链表List List Integer edges作为邻接表用下标前提是数据从0开始计数作为 ”节点“链表的值作为 ”与该节点相连的节点列表“。也可以使用哈希表来映射Map Integer, List Integer edges入度数组本题我们在进行拓扑排序的过程中还需要知道节点的入度值因此我们为了方便可以用一个入度数组in来记录图中所有节点的入度值。int[]innewint[numCourses];代码实现classSolution{publicbooleancanFinish(intnumCourses,int[][]prerequisites){// 顶点, 连接的节点列表MapInteger,ListIntegeredgesnewHashMap();// 邻接表存放图int[]innewint[numCourses];// 用于记录每一个顶点的入度值// 建图for(int[]prerequisite:prerequisites){// prerequisites[a][b] - 要学习a必须先学习b - b是a的前提/b有一条路径指向aintaprerequisite[0],bprerequisite[1];// b - aif(!edges.containsKey(b)){// 判断邻接表中是否存在顶点(b)edges.put(b,newArrayList());// 将顶点存入邻接表中}edges.get(b).add(a);// 将与顶点连接的节点添加到节点列表in[a];// 更新连接b节点的入度值}// 拓扑排序(用来判断图中是否存在环:存在-true/不存在-false)QueueIntegerqueuenewArrayDeque();// 队列用于存放入度值为0的顶点// 1.将入度值为0的顶点放入队列for(intx0;xnumCourses;x){if(in[x]0){queue.offer(x);}}// 2.层序遍历/BFSwhile(!queue.isEmpty()){inttopqueue.poll();// 取出队首元素// 遍历队首元素对应的节点列表,将列表中的所有节点的入度值减一(删除连接线)for(intx:edges.getOrDefault(top,newArrayList())){// 将入度值减一之后判断入度值是否为0(为0时是顶点,要放入队列)if(--in[x]0){queue.offer(x);}}}// 判断图中是否存在环(若入度数组in的所有值都为0则图中不存在环)for(intx:in){if(x!0){// 不为0,有环returnfalse;}}// 返回truereturntrue;}}完

相关新闻

MySQL中的常用SQL语句

MySQL中的常用SQL语句

SQL语句的分类DDL(Data Definition Languages)语句:数据定义语言,这些语句定义了不同的数据段、数据库、表、列、索引等数据库对象的定义。常用的语句关键字主要包括 create、drop、alter、rename、truncate。其中 create 用于创建数据库对象,drop 用于删…

2026/10/10 2:58:07 阅读更多 →
Python 高阶语法(二):上下文管理器、with、yield 与资源安全释放——从文件到 FastAPI 数据库会话

Python 高阶语法(二):上下文管理器、with、yield 与资源安全释放——从文件到 FastAPI 数据库会话

这一篇我们会学习另一个在后端中非常重要的能力:with __enter__ __exit__ contextmanager yield async with它们会解释为什么文件、数据库连接、HTTP 客户端、模型资源都需要被正确打开和关闭。一、前言在编程中,有很多资源不能只打开、不关闭。例如&…

2026/10/10 2:58:07 阅读更多 →
第16章-RAG

第16章-RAG

第 16 章:RAG 在模型回答前检索可信外部知识,把相关证据加入 Prompt,让回答更贴近私有数据并具备可追溯来源。 前言 模型参数中没有企业最新制度、内部文档和实时知识。RAG(Retrieval-Augmented Generation)不要求重新…

2026/10/10 2:58:07 阅读更多 →

最新新闻

MATLAB联合CST建模:超表面仿真自动化工作流实战

MATLAB联合CST建模:超表面仿真自动化工作流实战

最近不少做超表面的同学都在折腾CST仿真,尤其是想把MATLAB联合CST建模这条路彻底走通,用来处理超透镜、轨道角动量、吸收器、极化转换器、EIT(类电磁诱导透明)这些常见方向。这篇文章不打算讲教科书推导,只写我在真实仿…

2026/10/10 3:48:27 阅读更多 →
PostgreSQL权限管理实战:角色体系、层级授权与行级安全

PostgreSQL权限管理实战:角色体系、层级授权与行级安全

1. 权限分配这件事,先搞懂 PostgreSQL 的角色体系做数据库运维这些年,我发现一个特别有意思的现象:很多人对 PostgreSQL 的权限管理第一反应是“这不就是 grant 一下嘛”,可真到了线上环境,经常被各种“没权限”“权限…

2026/10/10 3:48:26 阅读更多 →
1996-2024年各省农业总产值无缺失面板数据:从处理到分析完整指南

1996-2024年各省农业总产值无缺失面板数据:从处理到分析完整指南

做农业数据分析的人应该都有过这种经历:想研究各省农业生产的长期变化,打开官方数据库发现要么年份对不上,要么某些省份某几年突然缺了一块,要么当年价格和可比价格混在一起,搞不清谁是谁。最后大量时间花在找数据、拼…

2026/10/10 3:48:26 阅读更多 →
SCSI磁盘实战指南:从协议原理到Linux诊断调优

SCSI磁盘实战指南:从协议原理到Linux诊断调优

1. 项目概述:为什么“SCSI磁盘”这个老词还在工程师的日常对话里反复出现你可能在服务器机房巡检时听到运维同事说“这台存储柜挂了两块SCSI盘,热备没切过去”,也可能在旧系统迁移文档里看到“需兼容SCSI-3 SPI协议的磁盘阵列”,甚…

2026/10/10 3:48:26 阅读更多 →
PostgreSQL自定义函数规范:从命名到性能排查的完整指南

PostgreSQL自定义函数规范:从命名到性能排查的完整指南

1. 为什么自定义函数必须讲规范1.1 从一次线上事故说起先说一个我亲眼见过的教训。某公司的订单系统,早期为了赶业务进度,开发人员在 PostgreSQL 里写自定义函数时完全放飞自我——函数名有的叫get_data、有的叫f_order,参数类型混用 varchar…

2026/10/10 3:48:26 阅读更多 →
PyTorch+LSTM电影评论情感分析实战:从预处理到模型部署

PyTorch+LSTM电影评论情感分析实战:从预处理到模型部署

简介:一份评审分达99分的基于深度学习的电影评论情感分析项目资源包,适合计算机相关专业课程设计、期末大作业及入门实战,重点解决从数据爬取到模型训练演示中缺完整代码、缺数据集、缺文档的常见问题。资源围绕豆瓣短评设计,约5万…

2026/10/10 3:47:26 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →