拓扑排序(Topological Sorting)

news2024/11/30 0:48:07

题目描述

题目链接:剑指 Offer II 113. 课程顺序 - 力扣(Leetcode)

现在总共有 numCourses 门课需要选,记为 0numCourses-1

给定一个数组 prerequisites ,它的每一个元素 prerequisites[i] 表示两门课程之间的先修顺序。 例如 prerequisites[i] = [ai, bi] 表示想要学习课程 ai ,需要先完成课程 bi

请根据给出的总课程数 numCourses 和表示先修顺序的 prerequisites 得出一个可行的修课序列。

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

示例 1:

输入: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]
输出: [0,1,2,3] or [0,2,1,3]
解释: 总共有 4 门课程。要学习课程 3,你应该先完成课程 1 和课程 2。并且课程 1 和课程 2 都应该排在课程 0 之后。
因此,一个正确的课程顺序是 [0,1,2,3] 。另一个正确的排序是 [0,2,1,3]

请添加图片描述

示例 2:

输入:numCourses = 2, prerequisites = [[1,0],[0,1]]
输出:[]

提示:

  • 1 <= numCourses <= 105
  • 0 <= prerequisites.length <= 5000
  • prerequisites[i].length == 2
  • 0 <= ai, bi < numCourses
  • prerequisites[i] 中的所有课程对 互不相同

拓扑排序

我们会把生产流程、软件开发、课程安排等都当成一个项目工程来对待,所有的工程都可分为若干个 “活动“ 的子工程。在这些活动之间,通常会受到一定的条件约束,如其中某些活动必须在另一些活动完成之后才能开始。就像上图 1 课程要在 0 课程之后学,3 课程要在 1 课程之后学。因此这样的工程图,一定是无环的有向图。

G=(V,E) 是一个具有 n 个顶点的有向图,V 中的顶点序列 v 1 , v 2 , . . . v n v_1, v_2, ... v_n v1,v2,...vn,若满足有从顶点 v i v_i vi v j v_j vj 的路径,则顶点序列中 v i v_i vi v j v_j vj 之前。那么称这样的顶点序列为一个拓扑序列。

所谓拓扑排序,就是对一个有向图构造拓扑序列的过程。

同时,也需要了解入度出度的概念:

  • 入度:以该顶点为终点的有向边数量,即有多少条边直接指向该顶点

  • 出度:以该顶点为起点的有向边数量,即由该顶点指出的边有多少

因此,对于有向图的拓扑排序,可以使用如下思路输出拓扑序列(BFS):

  1. 开始时,将所有入度为 0 的顶点加入队列
    • 入度为 0,说明没有边指向该顶点,放到拓扑序列的首部,不会违反定义
  2. 在队列中进行出队操作,出队顺序就是我们要找的拓扑序列。对于当前弹出的顶点 x,遍历 x 的所有出度,即所有由 x 指向的顶点 y,对 y 做入度减 1 操作
    • 因为 y 需要的一个前提已经准备就绪了,就可以其减去
  3. 对 y 进行减 1 操作后,检查 y 的入度是否为 0,如果为 0 则将 y 入队
    • 如果 y 所有前提都准备好了,就可以执行 y 操作了
  4. 循环流程 2、3 直到队列为空

建图 + 拓扑排序

回到本题,我们可以根据题目给出的 prerequisites 建图。若课程 a 存在前置课程 b 的话,就添加一条从 b 到 a 的有向边,同时统计所有课程的入度。

当建完图后,将所有入度为 0 的课程进行入队操作,进行拓扑排序,若得到的序列的课程数等于给出的课程数,说明有合理的顺序,否则返回空。

代码:

class Solution {
public:
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
        vector<vector<int>> edges(numCourses);
        // 用来记录每个顶点的入度
        vector<int> inDeg(numCourses);              
        // 建图并记录入度
        for (const auto& pre : prerequisites) {
            edges[pre[1]].push_back(pre[0]);
            inDeg[pre[0]]++;
        }
        
        queue<int> q;
        // 将度为 0 入队
        for (int i = 0; i < numCourses; i++) {
            if (inDeg[i] == 0) {
                q.push(i);
            }
        }

        vector<int> ans;
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            ans.push_back(u);
            for (int v : edges[u]) {
                inDeg[v]--;
                if (inDeg[v] == 0) {
                    // 此时说明前置课程都学习过了
                    q.push(v);
                }
            }
        }
        return (ans.size() == numCourses) ? ans : vector<int>();
    }
};
  • 时间复杂度: O ( m + n ) O(m + n) O(m+n),其中 n 为课程数,m 为先修课程的要求数,
  • 空间复杂度: O ( m + n ) O(m + n) O(m+n)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/84997.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端给后端发送数据,后端接收

在具体的前后端分离项目中&#xff0c;我们经常会遇到点击表格中的某一行的按钮&#xff0c;获取这一行的某一项值的需求&#xff0c;前端点击拿到这个值&#xff0c;再传给后端使用 例如&#xff1a;在此例中点击同步的按钮&#xff0c;需要获取到表格中的ip地址的内容&#…

GD32F303固件库开发(17)----内部Flash读写

概述 本例程主要讲解如何对芯片自带Flash进行读写&#xff0c;用芯片内部Flash可以对一些需要断电保存的数据进行保存&#xff0c;无需加外部得存储芯片&#xff0c;本例程采用的是GD32F303ZET6主控&#xff0c;512K大小的Flash。 最近在弄ST和GD的课程&#xff0c;需要GD样片…

web前端期末大作业:基于HTML+CSS+JS外卖服务平台10页 带购物车 (web课程设计与实现)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

Yolo v5源码解析笔记

一、Yolo v5文件目录树结构 二、train.py文件介绍 从main()方法&#xff0c;首先读取参数&#xff1b;其次建立YOLONet&#xff1b;然后读取训练数据&#xff1b;最后进行训练。 2.1 读取参数 部分截图 2.2 建立YOLONet YOLONet的建立是通过 yolo文件夹中的yolo_net.py文件…

游戏开发58课 性能优化

6. 卡顿优化 相信很多研发者或玩家&#xff0c;都遇到这种情况&#xff1a;游戏大部时间运行都很流畅&#xff0c;但在战斗的某些时刻或者打开某些界面会卡一下&#xff0c;甚至卡很久。这个现象就是卡顿。引发卡顿的原因有很多&#xff0c;但主要有&#xff1a; 突发大量IO。…

银河麒麟桌面V10SP1版本系统休眠唤醒鼠标键盘失效解决方法

使用银河麒麟桌面系统有时会出现系统休眠后再唤醒&#xff0c;鼠标键盘失效的问题&#xff0c;可尝试以下方法解决。 1.检查是否安装 laptop-mode-tools 工具 执行命令: dpkg -l | grep laptop-mode-tools如果执行命令无结果输出&#xff0c;表示未安装(如果已安装&#xff0…

【从零开始学习深度学习】21. 卷积神经网络(CNN)之二维卷积层原理介绍、如何用卷积层检测物体边缘

目录1. 二维互相关运算2. 自定义二维卷积层3. 卷积层的应用----图像中物体边缘检测4. 通过数据学习核数组5. 互相关运算和卷积运算6. 特征图和感受野总结卷积神经网络&#xff08;convolutional neural network&#xff09;是含有卷积层&#xff08;convolutional layer&#x…

欧克科技在深交所上市:客户集中度较高,胡坚晟为控股股东

12月12日&#xff0c;欧克科技股份有限公司&#xff08;下称“欧克科技”&#xff0c;SZ:001223&#xff09;在深圳证券交易所主板上市。本次上市&#xff0c;欧克科技的发行价格为65.58元/股&#xff0c;发行数量为1668万股&#xff0c;募资总额约为10.94亿元&#xff0c;募资…

印制电路板(PCB)设计原则和抗干扰措施

印制电路板(PCB)是电子产品中电路元件和器件的支撑件&#xff0e;它提供电路元件和器件之间的电气连接。随着电于技术的飞速发展&#xff0c;PCB的密度越来越高。PCB 设计的好坏对抗干扰能力影响很大&#xff0c;因此&#xff0c;在进行PCB 设计时&#xff0e;必须遵守PCB设计的…

Nginx 防盗链

Nginx 防盗链 本篇主要介绍一下 nginx 中 防盗链的具体配置 , 以及http 的 referer 头 概述 防盗链其实就是 防止别的站点来引用你的 资源, 占用你的流量 在了解nginx 防盗链之前 我们先了解一下 什么是 HTTP 的头信息 Referer,当浏览器访问网站的时候,一般会带上Referer,告…

【TS】TypeScript声明文件(.d.ts)的使用

前言 当我们在TS文件中需要引入外部库时&#xff0c;编译时是无法判断传入参数的类型的&#xff0c;所以我们需要在引入前加入一个声明文件来帮助ts判断类型。 当然现在大部分库都自带有自己的声明文件&#xff0c;一般在types目录下。 使用场景 在ts文件中对引用的外部库做…

汇编逻辑运算指令

目录 逻辑运算指令 一&#xff1a;取反指令NOT 二&#xff1a;逻辑与运算AND&#xff08;重点&#xff09; 屏蔽某些位. 把小写字母转换成大写字母 判断一个数的状态 三&#xff1a;逻辑或运算指令OR 用于拼字 把大写字母转换为小写字母 四&#xff1a;逻辑异或指令XOR…

程序员也会八卦吗?

世俗的眼光&#xff0c;总是觉得女生喜欢吃八卦&#xff0c;经常聚在一起小圈子叽叽喳喳谈论朋友圈。 其实&#xff0c;从现实来看&#xff0c;办公室的男性同胞也不啻于女生的八卦程度。 在吃瓜这件问题上&#xff0c;程序员凭借自身的技术优势&#xff0c;往往奋战于最前线…

【网络编程】捕获网卡IP数据报

本文将通过winsock从应用层捕捉网络层的IP数据报。 唉&#xff0c;原来的时候一直希望能在应用层实现网络游戏加速&#xff0c;发现可以捕捉网卡IP数据报后觉得可能有希望写出来。后面想了想得出结论&#xff1a;可以捕获没卵用&#xff0c;因为没法拦截&#xff08;包已经发出…

RocketMQ的事务消息是如何实现的?

RocketMQ的事务消息实现方法如下&#xff1a; 1、首先生产者订单系统先发送⼀条half消息到Broker&#xff0c;half消息对消费者而⾔是不可⻅的 2、再创建订单&#xff0c;根据创建订单成功与否&#xff0c;向Broker发送commit或rollback 3、并且⽣产者订单系统还可以提供Broker…

Spark 3.0 - 11.ML 随机森林实现二分类实战

目录 一.引言 二.随机森林实战 1.数据预处理 2.随机森林 Pipeline 3.模型预测与验证 三.总结 一.引言 之前介绍了 决策树 &#xff0c;而随机森林则可以看作是多颗决策树的集合。在 Spark ML 中&#xff0c;随机森林中的每一颗树都被分配到不同的节点上进行并行计算&…

Crack:Aspose.3D for .NET 22.11.X

Aspose.3D for .NETAspose.3D for .NET 是一个功能丰富的游戏软件和计算机辅助设计 (CAD) API&#xff0c;无需任何 3D 建模和渲染软件依赖即可操作文档。API 支持 Discreet3DS、WavefrontOBJ、FBX&#xff08;ASCII、二进制&#xff09;、STL&#xff08;ASCII、二进制&#x…

[附源码]Nodejs计算机毕业设计基于web的家教管理系统Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

linux信号:SIGINT、SIGKILL、SIGSTOP、SIGCONT

目录 1. SIGINT 2. SIGKILL 3. SIGSTOP与SIGCONT 简介 SignalStandardActionCommentSIGINTP1990TermInterrupt form keybordSIGKILLP1990TermKill signalSIGSTOPP1990TermInterrupt form keybord1. SIGINT 我们在shell交互式进程中常用的ctrl c 就是对当前运行的程序进行…

[附源码]Node.js计算机毕业设计电影票网上订票系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…