算法沉淀——拓扑排序

前言:

首先我们需要知道什么是拓扑排序?

在正式讲解拓扑排序这个算法之前,我们需要了解一些前置知识(和离散数学相关)

1、有向无环图:

指的是一个无回路的有向图。

入度:有向图中某点作为图中边的终点的次数之和

出度:有向图中某点作为图中边的起点的次数之和

2、AOV网:顶点活动图

在有向无环图中,用顶点来表示一个活动,用边来表示活动的先后顺序的图结构。

举个例子:

在下面的这张图中,1这个点的入度就是0,2这个点的入度就是2,因为有两条有向线段指向2这个点。

3、拓扑排序:

简而言之就是找到事情的先后顺,拓扑排序的结果可能不是唯一的。

如何排序?

  1. 找出图中入度为0的点,然后输出
  2. 删除与该点连接的边
  3. 重复1、2操作,直到图中没有点或者没有入度为0点为止。(有可能有环

重要应用:判断有向图中是否有环

4、如何用代码实现拓扑排序呢?(重点)

首先,我们需要根据题意去建图!!!(利用哈希表等容器,会结合题目详细解析)。

接着,建好图后,借助队列,来一次BFS即可。

1、初始化:把所有入度为0的点加入到队列中

2、当队列不为空时:

  1. 拿出队头元素,加入到最终结果中;
  2. 删除与该元素相连的边
  3. 判断:与删除边相连的点,是否入度变成0,如果入度为0,加入到队列中

经典例题1:207. 课程表 - 力扣(LeetCode)

题目描述:

题目解析:

我们可以根据题意,将课程之间的联系抽象成图

而题目所说的判断能否完成所有的课程学习,问的就是这个图有无环!!!

知道本题利用拓扑排序解决,那第一步就是如何建图呢

灵活使用语言提供的容器

邻接表:

我们可以利用哈希表来实现图中点与点之间的关系。

同时我们也需要另一个容器存储每个点的入度。

原码:

class Solution {
public:bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {unordered_map<int,vector<int>> hash; //邻接表存图vector<int> in(numCourses); //标记每个点的入度//开始建图for(auto& e : prerequisites){int a = e[0];int b = e[1];hash[b].push_back(a);in[a]++;}queue<int> q;//将度为0的边存到队列中for(int i = 0; i < numCourses; i++)//{cout << i << endl;if(in[i] == 0) q.push(i);}//进行拓扑排序bfswhile(q.size()){int t = q.front();q.pop();//将这个点删除,并且删除跟他相连的边for(int i : hash[t]){in[i]--;if(in[i] == 0) q.push(i);}}//判断是否有环for(auto i : in){if(i > 0) return false;}return true;}
};

例题二:LCR 114. 火星词典 - 力扣(LeetCode)

题目描述:

题目解析:

本题也是拓扑排序的经典例题。

1、如何搜集信息?

两层for循环

2、拓扑排序:

1、建图

hash<char, hash<char>> edges;

注意第一个hash表示map类型,第二个hash表示set。

这就需要我们对容器的灵活使用!

2、统计入度信息

hash<char, int> in; 注意必须要初始化

3、如何收集信息:双指针

4、细节问题:

abc和ab,若abc在前明显不符合要求,需要提前返回空字符串。

原码:

class Solution {
public:string alienOrder(vector<string>& words) {unordered_map<char, unordered_set<char>> edges; // 邻接表来存储图unordered_map<char, int> in; // 统计入度string ans;int n = words.size();//必须要对入度进行初始化,不然入度为0的点根本没有存进去for(auto& i : words){for(auto k : i)in[k] = 0;}for(int i = 0; i < n; i++){for(int j = i + 1; j < n; j++){string a = words[i];string b = words[j];int len1 = a.size(), len2 = b.size();int len = min(len1, len2);int flag = 0;for(int k = 0; k < len; k++){//正常情况if(a[k] != b[k]){if(!edges.count(a[k]) || !edges[a[k]].count(b[k])){edges[a[k]].insert(b[k]);in[b[k]]++;}flag = 1;break;}}//判断特殊情况if(len1 > len2 && !flag){return ans;}}}//开始拓扑排序queue<char> q;//注意map的范围for表示!!!for(auto& [a, b]: in){if(b == 0){q.push(a);}}while(q.size()){char tmp = q.front();q.pop();ans += tmp;cout << ans << endl;for(char i : edges[tmp]){in[i]--;if(in[i] == 0) q.push(i);}}//判断是否有环for(auto& [a,b] : in){if(b != 0) return "";}return ans;} 
};

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

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

相关文章

element-ui-plus el-tree 树形结构如何自定义内容

element-ui-plus el-tree 树形结构如何自定义内容 本文提及的 elementUI 版本 为 elementUI Plus 版本 一、需求 项目中遇到一个需要设置权限的地方&#xff0c;但目录和权限是放在一起的&#xff0c;这样就很不好区分类别&#xff0c;为了区分类别&#xff0c;就需要自定义树…

jsp用户登录界面

主界面 <% page contentType"text/html;charsetUTF-8" language"java" %> <html> <head><meta charset"UTF-8"><title>登录界面</title> </head> <body bgcolor"#faebd7"> <form…

JavaSE day15 笔记

第十五天课堂笔记 数组 可变长参数★★★ 方法 : 返回值类型 方法名(参数类型 参数名 , 参数类型 … 可变长参数名){}方法体 : 变长参数 相当于一个数组一个数组最多只能有一个可变长参数, 并放到列表的最后parameter : 方法参数 数组相关算法★★ 冒泡排序 由小到大: 从前…

用grafana+prometheus+cadvisor监控容器指标数据,并查询当前容器的网速网络用量

前言 整理技术&#xff0c;在这篇文章中&#xff0c;将会搭建grafanaprometheuscadvisor监控容器&#xff0c;并使用一个热门数据看板&#xff0c;再监控容器的性能指标 dashboard效果 这个是node-exporter采集到的数据&#xff0c;我没装node-exporter&#xff0c;而且这也…

解决 linux 服务器 java 命令不生效问题

在Linux系统中&#xff0c;当你安装Java并设置了JAVA_HOME环境变量后&#xff0c;你可能需要使用source /etc/profile命令来使Java命令生效。这是因为/etc/profile是一个系统级的配置文件&#xff0c;它包含了系统的全局环境变量设置。 但是需要注意的是&#xff0c;source /e…

Centos服务器Open Gauss 部署

近期很多的项目由于信创要求使用一些国产的数据库&#xff0c;比如OpenGauss。OpenGuass是华为高斯DB的开源版&#xff0c;内核还是PostgreSQL&#xff0c;商业版是收费的。这里记录一下是如何安装部署 的。 官方中文文档 官方下载地址 部署要求 操作系统要求 ARM&#xff…

基于SSM框架的校园失物招领系统:从设计思路到实现细节

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 目录 一、项目简介 二、开发技术与环…

java的多态和final关键字

多态&#xff1a; 多态分为对象多态&#xff0c;行为多态 多态的前提&#xff1a; 有继承/实现关系&#xff1b;存在父类引用子类对象&#xff1b;存在方法重写&#xff1b; 注意&#xff1a;多态是对象&#xff0c;行为的多态&#xff0c;java的成员变量不谈多态 这是我写…

mysql5.7 源码分析--初始化

集中在sql\mysqld.cc文件的mysqld_main函数中&#xff08;&#xff09;&#xff1a; 主程序入口 在sql\main.cc文件中&#xff1a; int main(int argc, char **argv) {return mysqld_main(arg, argv); } 一、mysql为了跨平台&#xff0c;对win32系统做了单独的初始化&#x…

【Docker】搭建强大易用的个人博客 - Halo

【Docker】搭建强大易用的个人博客 - Halo 前言 本教程基于绿联的NAS设备DX4600 Pro的docker功能进行搭建&#xff0c;采用Halo MySQL实例作为演示。 简介 Halo [ˈheɪloʊ] 是一个简洁&#xff0c;现代&#xff0c;快速且非常灵活的建站工具&#xff0c;它是由一位中国开…

统信 UOS V20 一键安装 Oracle 11GR2(231017)单机版

Oracle 一键安装脚本&#xff0c;演示 统信 UOS V20 一键安装 Oracle 11GR2&#xff08;231017&#xff09;单机版过程&#xff08;全程无需人工干预&#xff09;&#xff1a;&#xff08;脚本包括 ORALCE PSU/OJVM 等补丁自动安装&#xff09; ⭐️ 脚本下载地址&#xff1a;…

机器人码垛机:智能仓储系统的重要组成部分

随着科技的飞速进步&#xff0c;机器人技术已经渗透到了许多行业领域&#xff0c;其中&#xff0c;仓储业尤为显著。机器人码垛机作为智能仓储系统的重要组成部分&#xff0c;不仅提高了码垛效率&#xff0c;还降低了人工成本和安全风险。然而&#xff0c;在其广泛应用的同时&a…