算法沉淀——拓扑排序

news2024/11/29 6:32:13

前言:

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

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

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);
        }
        //进行拓扑排序bfs
        while(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.coloradmin.cn/o/1556236.html

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

相关文章

微服务(基础篇-007-RabbitMQ部署指南)

目录 05-RabbitMQ快速入门--介绍和安装_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1LQ4y127n4?p65&vd_source60a35a11f813c6dff0b76089e5e138cc 1.单机部署 1.1.下载镜像 1.2.安装MQ 2.集群部署 2.1.集群分类 2.2.设置网络 视频地址&#xff1a; 05-Rab…

Topaz Gigapixel AI for Mac 图像放大软件

Topaz Gigapixel AI for Mac是一款专为Mac用户设计的智能图像放大软件。它采用了人工智能技术&#xff0c;特别是深度学习算法&#xff0c;以提高图像的分辨率和质量&#xff0c;使得图像在放大后仍能保持清晰的细节。这款软件的特点在于其能够将低分辨率的图片放大至高分辨率&…

银河麒麟V10:sudo: /usr/bin/sudo 必须属于用户 ID 0(的用户)并且设置 setuid 位

一、引起原因&#xff1a; sudo chmod -R 777 bin 修改了/usr/bin/sudo的权限&#xff0c;引发后续问题。 二、现象&#xff1a; sudo执行命令报错&#xff1a; sudo: /usr/bin/sudo 必须属于用户 ID 0(的用户)并且设置 setuid 位 三、解决方法&#xff08;知道root密码&…

Java复习第十四天学习笔记(CSS),附有道云笔记链接

【有道云笔记】十四 3.30 CSS https://note.youdao.com/s/3VormGXs 一、CSS定义和基本选择器 CSS定义&#xff1a;cascading style sheet 层叠样式表。 语法&#xff1a; 选择器 { 属性名1:属性值1; 属性名2:属性值2; 属性名3:属性值3; 属性名4:属性值4; } CSS使用&a…

经典永不过时 Wordpress模板主题

经得住时间考验的模板&#xff0c;才是经典模板&#xff0c;带得来客户的网站&#xff0c;才叫NB网站。 https://www.jianzhanpress.com/?p2484

基于大数据的学习资源推荐系统的设计与实现(论文+源码)_kaic

摘 要 本文首先实现了学习资源推送管理技术的发展&#xff0c;随后依照传统的软件开发流程&#xff0c;最先为系统挑选适用的语言和软件开发平台&#xff0c;依据需求分析开展控制模块制作和数据库查询构造设计&#xff0c;依据系统整体功能模块的设计&#xff0c;制作系统的功…

武汉星起航引领亚马逊跨境电商新浪潮,助推卖家向全球拓展

在全球化的浪潮中&#xff0c;跨境电商以其独特的魅力和无限潜力&#xff0c;正成为推动国际贸易发展的重要引擎。亚马逊&#xff0c;作为全球电商平台的佼佼者&#xff0c;以其卓越的技术、高效的服务和广阔的市场覆盖&#xff0c;引领着跨境电商的新风潮。而在这股风潮中&…

JUC并发编程——对于synchronized关键字的理解

现象&#x1f50d;&#xff1a; 两个线程对初始值为 0 的静态变量一个做自增&#xff0c;一个做自减&#xff0c;各做 5000 次&#xff0c;最后输出的 counter一定为0 吗&#xff1f; Slf4j(topic "c.Test17") public class Test17 {static int counter 0;public…

Js逆向简单分析-某网站登录案例

文章目录 概要整体流程1.打开网站&#xff0c;输入数据进行登录2.对getlogin.php进行查看分析3.对于登录请求连接进行断点调试4.堆栈跟踪5.在网络上找在线md5加密 友情推荐 概要 某网站登录流量包逆向分析。 整体流程 1.打开网站&#xff0c;输入数据进行登录 用户名&#…

【C语言基础】:自定义类型(一)--> 结构体

文章目录 一、内置类型与自定义类型1.1 内置类型&#xff08;基本数据类型&#xff09;1.2 自定义类型 二、结构体2.1 结构体的声明2.2 结构体变量的创建和初始化2.3 结构体的特殊声明2.4 结构体的自引用 三、结构体内存对齐3.1 对齐规则3.2 为什么存在内存对齐3.3 修改默认对齐…

基于java+SpringBoot+Vue的校友社交系统设计与实现

基于javaSpringBootVue的校友社交系统设计与实现 开发语言: Java 数据库: MySQL技术: SpringBoot MyBatis工具: IDEA/Eclipse、Navicat、Maven 系统展示 前台展示 后台展示 系统简介 整体功能包含&#xff1a; 校友社交系统是一个为校友提供一个交流互动、信息共享的平台…

【高数】汤家凤高等数学辅导讲义+1800错题整理

第一章 极限与连续 1. 2. 3. 4. 5. 6. 7. 第二章 导数与微分 高等数学辅导讲义 1. 2. 3. 4. 5. 6. 7. 8. 1800 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 第三章 一元函数微分学的应用 高等数学辅导讲义 中值定理 题型一 题型二 题型三 题型四 题型五 单调性、极值与…

三菱GX WORKS3连接FX5U系列PLC时,弹出窗口提示:用户认证功能或安全性强化模式未启用

三菱GX WORKS3连接FX5U系列PLC时&#xff0c;弹出窗口提示&#xff1a;用户认证功能或安全性强化模式未启用 如下图所示&#xff0c;使用GX WORKS3编程软件连接FX5U系列PLC&#xff0c; 首先&#xff0c;在连接目标中选择自己当前使用的网卡适配器&#xff0c;并将IP地址设置在…

HuTool工具箱验证JWT生成Token失败

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于…

IC-随便记

1、移远通信---通信模组 物联网解决方案供应商&#xff0c;可提供完备的IoT产品和服务&#xff0c;涵盖蜂窝模组(5G/4G/3G/2G/LPWA)、车载前装模组、智能模组&#xff08;5G/4G/边缘计算&#xff09;、短距离通信模组(Wi-Fi&BT)、GNSS定位模组、卫星通信模组、天线等硬件产…

【全栈小5】我的创作纪念日

目录 前言机缘收获粉丝和原创个人成就六边形战士 回顾文章原代码代码优化 憧憬 前言 全栈小5 &#xff0c;有幸再次遇见你&#xff1a; 还记得 2019 年 03 月 29 日吗&#xff1f; 你撰写了第 1 篇技术博客&#xff1a; 《前端 - 仿动态效果 - 展开信息图标》 在这平凡的一天&…

直播上瘾?

目前我们正处在日新月异高速发展的时代&#xff0c;各行各业都在接入 AI&#xff0c;各行各业都在涌向直播的时代。当然&#xff0c;历史的车轮不会因为个人的喜好而改变&#xff0c;我们唯一能做的就是拥抱变化&#xff0c;这样才不会活的很别扭。 “ PS&#xff1a;这就是我为…

网络安全:绕过 MSF 的一次渗透测试

这次渗透的主站是 一个 Discuz!3.4 的搭建 违法招 piao 网站&#xff0c; 配置有宝塔 WAF 用 Discuz!ML 3.X 的漏洞进行攻击&#xff0c;但是没有成功 发现主站外链会有一个发卡网&#xff0c;引导人们来这充值&#xff0c;是 某某发卡网&#xff0c;而且域名指向也是主站的 ip…

一篇文章带你搞定企业级完整性能测试流程!

大部分公司在最初试的阶段只会关心项目的基本功能&#xff0c;能用就可以。但是随着项目的成熟&#xff0c;用户量逐步的增大&#xff0c;线上经常就会出现一些系统崩溃&#xff0c;用户反映系统太慢等性能问题的爆发。所以&#xff0c;性能测试的需求就逐步变得迫切了。所以&a…

照片分享,欢迎家庭新成员HPE ProLiant DL580 Gen9

正文共&#xff1a;1234 字 29 图&#xff0c;预估阅读时间&#xff1a;1 分钟 距离上一台服务器HPE ProLiant DL360 Gen9开箱已经过去4年了&#xff0c;回忆满满&#xff08;风雨同舟&#xff0c;感谢HP Proliant DL360 Gen9陪我走过的四年&#xff09;&#xff1b;就在上周&a…