【优选算法专栏】专题十八:BFS解决拓扑排序(一)

本专栏内容为:算法学习专栏,分为优选算法专栏,贪心算法专栏,动态规划专栏以及递归,搜索与回溯算法专栏四部分。 通过本专栏的深入学习,你可以了解并掌握算法。

💓博主csdn个人主页:小小unicorn
⏩专栏分类:算法从入门到精通
🚚代码仓库:小小unicorn的代码仓库🚚
🌹🌹🌹关注我带你学习编程知识

专题十八

  • 课程表
    • 算法原理:
  • 课程表 II
    • 算法原理:
  • 总结:

课程表

你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。

在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。

例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。
请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。

在这里插入图片描述

算法原理:

本题题意要先搞懂,举个例子:
在这里插入图片描述
假设传入的这个数组,以[1,0]来说,它的意思就是要想先修1,就必须先学习0这门课程,依次内推。想这个我们可以画个箭头好理解:0->1 意思就是学1要先学0;

分析到这,我们就可以把这个数组抽象出来:
在这里插入图片描述
这个图是不是很熟悉,这不就是我们的有向图吗?

看一下题目问的啥,问能否修完?那这问题的本质不就是给这个图能否拓扑排序,或者问这个图是不是有环.

分析到这,其实就可以动手写代码了,但是我们前言末尾说到过,实现拓扑排序的前提是要建图。我们先打一下理论基础,看如何建图:

首先如何灵活建图的前提我们要合理用我们的容器。
其次要看数据的稠密也就是数据量,我们通常有两种办法:

  1. 邻接矩阵
  2. 邻接表
    邻接矩阵市面上书籍讲的很多,这里我们采用邻接表的形式。
    什么是邻接表呢?
    在这里插入图片描述
    以刚才例子为例,我们把每个位置相连的点都放在一排,所形成的这个表就是邻接表。

可能有人好奇,那我们岂不是要实现一个链表,才能形成上面的对应关系,其实不然,我们用数组就可以模拟代替链表。

接下来我们可以选择合适的容器,也就是代码如何实现,这里我们给出两种:

  1. vector
    我们在vector里嵌套一个vector:
vector<vector<int>> edge;//edge边的意思

为什么二维数组就可以呢?
在这里插入图片描述
我们让其下标具有对应关系,咱们得邻接表不就出来了。

  1. 哈希表

用哈希表来实现邻接表:

unordered_map<int,vector<int>> edge;
unordered_map<string,vector<string>> edge;

在这里插入图片描述
用哈希来反映映射也是可以的。

代码实现:

class Solution 
{
public:bool canFinish(int n, vector<vector<int>>& prerequisites) {//1.准备工作unordered_map<int,vector<int>> edge;//邻接表存图//vector<vector<int>> edge(n);vector<int> in(n);//用来标记入度//2.建图for(auto& e:prerequisites){int a=e[0],b=e[1];  //b->a的一条边//拿到b的这条边//把a插入到b的后面edge[b].push_back(a);//有一条边指向a了,a入度++in[a]++;}//3.拓扑排序queue<int> q;//(1)把所有入度为0的点加入到队列中for(int i=0;i<n;i++){//入度为0if(in[i]==0)//加入队列q.push(i);}//(2)bfswhile(q.size()){int t=q.front();q.pop();//拿出点后,要把这个点相连的边删掉for(int a:edge[t]){//入度--in[a]--;//如果入度为0,进入队列if(in[a]==0)q.push(a);}}//4.判断是否有环for(int i=0;i<n;i++){if(in[i])return false;} return true;}
};

课程表 II

现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1。给你一个数组 prerequisites ,其中 prerequisites[i] = [ai, bi] ,表示在选修课程 ai 前 必须 先选修 bi 。

例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示:[0,1] 。
返回你为了学完所有课程所安排的学习顺序。可能会有多个正确的顺序,你只要返回 任意一种 就可以了。如果不可能完成所有课程,返回 一个空数组 。
在这里插入图片描述

算法原理:

本题跟课程表一模一样,只是返回的结果不一样,本题要返回一个序列,所以我们用一个数组统计一下信息即可。

代码实现:

class Solution 
{
public:vector<int> findOrder(int n, vector<vector<int>>& prerequisites) {//1.准备工作vector<vector<int>> edge(n);//用来储存图//unordered_map<int,vector<int>> edge;vector<int> in(n);//用来标记入度//2.建图for(auto& e:prerequisites){int a=e[0],b=e[1];  //b->a的一条边//把a插入到b的后面edge[b].push_back(a);//in[a]++;}//3.拓扑排序queue<int> q;vector<int> ret;//(1)把所有入度为0的点加入到队列中for(int i=0;i<n;i++){//入度为0if(in[i]==0)//加入队列q.push(i);}//(2)bfswhile(q.size()){int t=q.front();q.pop();ret.push_back(t);for(int a:edge[t]){//入度--in[a]--;//如果入度为0,进入队列if(in[a]==0)q.push(a);}}//4.判断是否有环if(ret.size()==n)return ret;else return {};}
};

总结:

其实用代码建图很简单,对于代码其实也就两三行的事情:

  1. 准备工作
//数组模拟
vector<vector<int>> edge(n)//n是大小
//哈希表模拟
unordered_map<int,vector<int>> edge;
//入度
vector<int> in(n);
  1. 建图
for(auto& e:prerequisites)
{int e[0]=a,e[1]=b;  b->a;//找到b这条边e[b].push_back(a);//有一条边指向了a//a入度++in[a]++;
}
  1. 拓扑排序

排序就根据前言分析的步骤实现。

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

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

相关文章

shamrockcms代码审计-啥也没有

shamrockcms 环境搭建 使用阿里源&#xff0c;创建数据库&#xff0c;运行shamrockcms.sql文件&#xff0c;将configure.properties中的jdbc修改为自己本地或者其他ip数据库连接&#xff0c;并且将ueditor.config.json中的master修改为localhost或者其他自己设置的ip 危险组件…

基于知识图谱的推理:智能决策与自动发现

基于知识图谱的推理&#xff1a;智能决策与自动发现 一、引言 在今天这个数据驱动的时代&#xff0c;我们经常会听到人们提及“知识图谱”这个词。知识图谱&#xff0c;作为一种结构化知识的表达方式&#xff0c;已经成为智能系统不可或缺的一部分&#xff0c;它通过连接大量的…

numpy,matplotilib学习(菜鸟教程)

所有内容均来自于&#xff1a; NumPy 教程 | 菜鸟教程 Matplotlib 教程 | 菜鸟教程 numpy模块 numpy.nditer NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。 for x in np.nditer(a, orderF):Fortran order&#xff0c;即是列序优先&#x…

三小时使用鸿蒙OS模仿羊了个羊,附源码

学习鸿蒙arkTS语言&#xff0c;决定直接通过实践的方式上手&#xff0c;而不是一点点进行观看视频再来实现。 结合羊了个羊的开发思路&#xff0c;准备好相应的卡片素材后进行开发。遇到了需要arkTS进行解决的问题&#xff0c;再去查看相应的文档。 首先需要准备卡片对应的图片…

【STL】顺序容器与容器适配器

文章目录 1顺序容器概述1.1array1.2forward_list1.3deque 2.如何确定使用哪种顺序容器呢&#xff1f;3.容器适配器的概念4.如何定义适配器呢&#xff1f; 1顺序容器概述 给出以下顺序容器表&#xff1a; 顺序容器类型作用vector可变大小的数组&#xff0c;支持快速访问&#…

lua学习笔记15(元表的学习)

print("*****************************元表的学习*******************************") print("*****************************元表的概念*******************************") --任何变量都可以作为另一个表变量的元表 --任何表变量都可以有自己的元表 --当我…

谷歌浏览器变黑色背景 扩展程序 Hacker Vision

这个扩展程序能够把浏览器的背景变成黑色&#xff0c;长时间阅读文章的时候护眼效果很不错 效果如下

《前端面试题》- JS基础 - call()、apply()、bind() 的区别

call 、bind 、 apply 这三个函数的功能都是改变this的指向问题&#xff0c;但是也存在一定的区别。 call 的参数是直接放进去的&#xff0c;第二第三第 n 个参数全都用逗号分隔,apply 的所有参数都必须放在一个数组里面传进去bind 除了返回是函数以外&#xff0c;它 的参数和…

美团一面:说说synchronized的实现原理?问麻了。。。。

引言 在现代软件开发领域&#xff0c;多线程并发编程已经成为提高系统性能、提升用户体验的重要手段。然而&#xff0c;多线程环境下的数据同步与资源共享问题也随之而来&#xff0c;处理不当可能导致数据不一致、死锁等各种并发问题。为此&#xff0c;Java语言提供了一种内置…

PUBG绝地求生29.1版本延迟高/卡顿/掉帧/丢包的快速解决方法

要想在绝地求生中获得好成绩&#xff0c;咱们需求把握一些根本的游戏技巧。比方&#xff0c;在挑选降落点时&#xff0c;咱们可以运用u标签来着重“安全”二字。挑选一个相对较为安全的降落点可以防止与其他玩家过早触摸&#xff0c;给自己争夺更多时间来搜集资源和配备。接下来…

ORAN C平面 Section Extension 22

ORAN C平面Section扩展22用于ACK/NACK请求。除section type 7外&#xff0c;section扩展22可以用于从O-DU发送到O-RU的所有section type和section扩展。 对于一个section描述&#xff0c;O-DU可以使用section扩展22要求O-RU使用section type 8 C平面消息进行ACK/NACK反馈。关于…

MyBatis源码介绍

文章目录 MyBatis的核心流程介绍SqlSessionFactory的理解MyBatis中的Executor的源码理解Spring中是如何解决MySQL的SqlSession的线程安全问题MyBatis面向Mapper编程工作原理Mybatis动态sql执行原理Mybatis的一级、二级缓存实现原理Mybatis的插件运行原理以及如何编写一个插件my…

制作一个RISC-V的操作系统十-Trap和Exception(流 mtvec mepc mcause mtval mstatus trap完整流程)

文章目录 流mtvecmepcmcausemtvalmstatustrap 初始化trap的top half&#xff08;硬件完成&#xff09;trap的bottom half&#xff08;软件完成&#xff09;从trap返回代码实现 流 控制流&#xff1a;程序控制的执行流 trap分为中断和异常 mtvec base&#xff1a;存储trap入…

2_8.Linux系统引导过程及引导修复

# 1.磁盘引导 # mbr主引导记录0磁道1扇区446 作用&#xff1a; 记录grub2引导文件的位置 当mbr数据丢失系统会因为找不到启动分区而停止启动 问题模拟方式: 系统磁盘/dev/sda dd if/dev/zero of/dev/vda bs446 count1 ##清空系统/dev/sda上的mbr数据 恢复方式&#xff1a; &…

图形化界面使用MQ!!!

一、docker安装 1、拉去镜像 docker pull rabbitmq:3.10-management 2、Docker运行&#xff0c;并设置开机自启动&#xff08;第一个-p是MQ默认配置的端口&#xff0c;第二个-p是图形化界面配置的端口&#xff09; docker run -d --restartalways --name rabbitmq -p 5672:5672…

直播系统的短视频直播源码,带有多功能后台系统的直播短视频平台 APP 源码。

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 此源码是一个直播系统&#xff0c;集直播、短视频等功能&#xff0c;根据市场趋势开发并推出思乐直播APP&#xff0c;APP功能丰富且可在后台管理系统进行配置&#xff0c;做到按需求来…

《QT实用小工具·二十二》多种样式导航按钮控件

1、概述 源码放在文章末尾 该项目实现了多种样式的导航按钮控件 可设置文字的左侧、右侧、顶部、底部间隔。 可设置文字对齐方式。 可设置显示倒三角、倒三角边长、倒三角位置、倒三角颜色。 可设置显示图标、图标间隔、图标尺寸、正常状态图标、悬停状态图标、选中状态图标…

ctfshow web入门 文件上传web162--web167

web162 session文件包含条件竞争 直接包含不传马了 我们上传的文件如果不符合要求&#xff0c;就会被删除&#xff0c;导致成功上传无法访问&#xff0c;没有用。但是如果我们上传的速度比服务器删的速度快&#xff0c;就可以了。 上传.user.ini GIF89a auto_append_file/tmp/…

四、书城开发--3、书城图书部分的开发

书城图书部分 首先我们做书城首页搜索栏下面的图片展示 我们在书城首页组件中通过home请求方法中获取回来的数据中&#xff0c;打印出来可以看到那个banner就是我们现在要的图片 我们在data中定义一个变量banner用来存放获取回来的数据中的banner 然后把它展示出来就可以了&a…

LeetCode-84. 柱状图中最大的矩形【栈 数组 单调栈】

LeetCode-84. 柱状图中最大的矩形【栈 数组 单调栈】 题目描述&#xff1a;解题思路一&#xff1a;单调栈解题思路二&#xff1a;解题思路三&#xff1a; 题目描述&#xff1a; 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且…