算法笔记(十五)——BFS 解决拓扑排序

news2024/10/10 9:43:06

文章目录

  • 拓扑排序
  • 课程表
  • 课程表 II
  • 火星词典

拓扑排序

有向无环图(DAG图)

  • 有向无环图指的是一个无回路的有向图

在这里插入图片描述

AOV网:顶点活动图

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

拓扑排序

  • 找到一个先后顺序,结果可能不唯一
  • 如何拓扑排序?
    • 找到一个入度为零的点,然后输出;
    • 删除与该点连接的边;
    • 重复上述操作,直至图中没有点或没有入度为零的点(图中有环);

  • 实现拓扑排序
  1. 初始化:将所有入度为0的点加入到队列中
  2. 当队列不空的时候,循环:
    1. 拿出队头元素,加入到结果中
    2. 删除与该元素相连的边
    3. 判断:与删除边相连的点入度是否为0;如果为0,将该点加入队列

课程表

题目:课程表

在这里插入图片描述

思路

  • 建立哈希表unordered_map<int, vector<int>> edges;存储有向图的边,edges[b].push_back(a);表示b->a
  • vector<int> in(numCourses);来表示节点的入度
  • 利用上述容器建图
  • 将入度为 0的节点加入队列q
  • BFS进行拓扑排序,入度为0的节点依次出队,并将其邻接节点的入度减1。如果邻接节点的入度减为0,将其加入队列
  • 判断是否有环:vector<int> in(numCourses);中入度都为0即不存在环,返回true

C++代码

class Solution 
{
public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) 
    {
        // 1. 初始化
        unordered_map<int, vector<int>> edges;
        vector<int> in(numCourses);

        // 2. 建图
        for(auto& e : prerequisites)
        {
            int a = e[0], b = e[1];
            edges[b].push_back(a);
            in[a]++;
        }

        // 3.拓扑排序
        queue<int> q;
        // 入度为 0 的点进队
        for(int i = 0; i < numCourses; i++)
        {
            if(in[i] == 0) q.push(i);
        }
        // BFS
        while(!q.empty())
        {
            auto t = q.front(); q.pop();
            for(auto e : edges[t])
            {
                in[e]--;
                if(in[e] == 0) q.push(e);
            }
        }
		
		// 4. 判断是否有环
        for(auto e : in)
        {
            if(e) return false;
        }
        return true;
    }
};

课程表 II

题目:课程表 II

在这里插入图片描述
思路

思路和上面一致,只需要在每次将入度为0的点顺序保存即为拓扑排序的顺序。

C++代码

class Solution 
{
public:
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) 
    {
        // 1. 初始化
        unordered_map<int, vector<int>> edges;
        vector<int> in(numCourses);

        // 2. 建图
        for(auto& e : prerequisites)
        {
            int a = e[0], b = e[1];
            edges[b].push_back(a);
            in[a]++;
        }

        // 3.拓扑排序
        queue<int> q;
        vector<int> ret;
        // 入度为 0 的点进队
        for(int i = 0; i < numCourses; i++)
        {
            if(in[i] == 0) q.push(i);
        }
        // BFS
        while(!q.empty())
        {
            auto t = q.front(); q.pop();
            ret.push_back(t);
            for(auto e : edges[t])
            {
                in[e]--;
                if(in[e] == 0) q.push(e);
            }
        }

        for(auto e : in)
        {
            if(e) return {};
        }
        return ret;
    }
};

火星词典

题目:火星词典

在这里插入图片描述

思路

理解题意:

如何搜集信息:

  1. 两层for循环枚举所有的两个字符串组合
  2. 利用双指针,找出字典序规则信息
  • 建图和初始化入度信息
unordered_map<char, unordered_set<char>> edges; // 邻接表存储图
unordered_map<char, int> in; // 节点入度
  • 添加边和检测冲突

    1. 对于单词列表中的每一对单词,比较它们相同位置上的字符。如果找到第一个不同的字符,则添加一条从该字符到另一个字符的边,并增加目标字符的入度。
    2. 如果一个单词是另一个单词的前缀且更长,则这表示存在冲突(因为按照字典序,更长的单词不应该出现在更短的单词之后),此时设置checktrue并返回空字符串表示无解
  • 拓扑排序

    1. 将所有入度为0的节点(字母)加入队列
    2. 取出节点,将其添加到结果字符串中,并减少其所有邻接节点的入度。如果某个邻接节点的入度变为0,则将其加入队列
    3. 重复上述过程直到队列为空
  • 判断成环:检查是否所有节点的入度都为0

C++代码

class Solution 
{
    unordered_map<char, unordered_set<char>> edges; // 邻接表存储图
    unordered_map<char, int> in; // 节点入度
    bool check = false;

    void add(string& s1, string& s2)
    {
        int n = min(s1.size(), s2.size());
        int i = 0;

        for(; i < n; i++)
        {
            if(s1[i] != s2[i])
            {
                // a -> b
                char a = s1[i], b = s2[i];
                if(!edges.count(a) || !edges[a].count(b))
                {
                    edges[a].insert(b);
                    in[b]++;
                }
                break;
            }
        }
        if(i == s2.size() && i < s1.size()) check = true;
    }
public:
    string alienOrder(vector<string>& words) 
    {
        // 1. 建图 + 初始化入度信息
        for(auto word : words)
            for(auto ch : word)
                in[ch] = 0;

        int n = words.size();
        for(int i = 0; i < n; i++)
        {
            for(int j = i + 1; j < n; j++)
            {
                add(words[i], words[j]);
                if(check) return "";
            }
        }

        // 2.拓扑排序
        queue<char> q;
        for(auto& [a, b] : in)
            if(b == 0) q.push(a);

        string ret;
        while(!q.empty())
        {
            char t = q.front(); 
            q.pop();

            ret += t;
            for(auto ch : edges[t])
            {
                in[ch]--;
                if(in[ch] == 0) q.push(ch);
            }
        }

        // 3.判断成环
        for(auto& [a, b] : in)
            if(b) return "";


        return ret;
    }
};

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

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

相关文章

鸿蒙HarmonyOS中Image图片组件以及HarmonyOs图标库完全解析

Image 图片组件&#xff0c;支持本地图片和网络图片的渲染展示。 一 、加载网络图片 1 、需要在 src/main/module.json5 中申请网络权限 "requestPermissions": [ { "name": "ohos.permission.INTERNET" } ] 详情参考&#xff1a; https://d…

展览会:企业宣传和推广的重要平台之一

在当今这个信息爆炸、市场竞争日益激烈的时代&#xff0c;展会作为企业与市场直接对话的重要桥梁&#xff0c;其推广的重要性愈发凸显。展会不仅是产品展示、技术交流的平台&#xff0c;更是品牌塑造、市场拓展的关键一环。 一、提升品牌知名度与形象 展会是企业向外界展示自…

新一届诺贝尔奖揭晓,能否为医学AI领域带来一些启发?|个人观点·24-10-09

小罗碎碎念 还未从microRNA的知识海洋中抽身出来&#xff0c;又要面对受限玻尔兹曼机带来的冲击。 这两天随着诺贝尔奖的公布&#xff0c;学术界可谓是热闹非凡&#xff0c;我也正好趁着这个机会&#xff0c;拾起停更半个月的公众号。 作为医学人工智能研究大军中的一员&#…

各省财政涉农支出统计(2001-2022年)

财政涉农支出是指政府预算中用于支持农业、农村和农民发展的财政支出&#xff0c;旨在促进农村经济的发展&#xff0c;提高农民收入&#xff0c;改善农村生产生活条件&#xff0c;推进农业现代化。 2001年-2022年各省财政涉农支出统计&#xff08;数据整理&#xff09;.zip资源…

Linux平台Kafka高可用集群部署全攻略

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《大数据前沿&#xff1a;技术与应用并进》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Kafka简介 2、Kafka核心优势 二、环境准备 1…

Android SELinux——安全策略(三)

SELinux 通过严格的访问控制机制增强了 Linux 系统的安全性。它通过标签和安全策略来控制进程和文件的访问权限&#xff0c;从而保护系统免受未经授权的访问和攻击。 一、策略介绍 1、主要组件 安全标签&#xff08;Security Labels&#xff09;&#xff1a;每个文件、目录、…

麒麟操作系统:解决sudo命令报错“Account or password is expired”问题

麒麟操作系统&#xff1a;解决sudo命令报错“Account or password is expired”问题 1、问题描述2、问题分析3、问题解决方法步骤1&#xff1a;检查账户和密码状态步骤2&#xff1a;处理账户过期问题步骤3&#xff1a;处理密码过期问题 &#x1f490;The Begin&#x1f490;点点…

电脑端视频通过PCIE到FPGA端图像缩放转UDP网络视频输出,基于XDMA+PHY芯片架构,提供3套工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐我已有的PCIE方案我这里已有的以太网方案本博已有的FPGA图像缩放方案 3、PCIE基础知识扫描4、工程详细设计方案工程设计原理框图电脑端视频PCIE视频采集QT上位机XDMA配置及使用XDMA中断模块FDMA图像缓存纯Verilog图像缩放模块详解…

Python - Modbus测试

python -Modbus测试 前言 本实例中&#xff0c;python版本是python 3.10, 使用的pymodbus安装包进行实现&#xff0c;如没有按照此包&#xff0c;需要先执行如下指令&#xff1a; pip install pymodbusModbus客户端的python实现 Modbus Client的客户端程序&#xff0c;通过…

【Java 问题】集合——List

List 1.说说有哪些常见集合&#xff1f;2.ArrayList和LinkedList有什么区别&#xff1f;3.ArrayList的扩容机制了解吗&#xff1f;4.ArrayList怎么序列化的知道吗&#xff1f; 为什么用transient修饰数组&#xff1f;5.快速失败(fail-fast)和安全失败(fail-safe)了解吗&#xf…

XILINX MIG驱动

简介 框架图 本章节主要针对MIG读写做详细介绍,首先创建BLOCK DESIGN,工程连接如下图所示: MIG IP介绍 DATAMOVER的配置这里不再做介绍,结合上篇文章讲到DATAMOVER对BRAM进行读写操作,这里通过AXI桥再加一个MIG模块,MIG模块的配置和说明如下: 1、Clock Period:…

记录一个Ajax发送JSON数据的坑,后端RequestBody接收参数小细节?JSON对象和JSON字符串的区别?

上半部分主要介绍我实际出现的问题&#xff0c;最终下面会有总结。 起因&#xff1a;我想发送post请求的data&#xff0c;但是在浏览器中竟然被搞成了地址栏编码 如图前端发送的ajax请求数据 如图发送的请求体&#xff1a; 很明显是keyvalue这种形式&#xff0c;根本就不是…

浏览器动态移动的小球源码分享

浏览器动态移动的小球源码分享 <script>(function(a){var width100,height100,borderRadius100,circlefunction(){};circle.prototype{color:function(){let colour "#"Math.floor(Math.random()*255).toString(16)Math.floor(Math.random()*255).toString…

基于SpringBoot剧本杀管理系统 【附源码】

基于SpringBoot剧本杀管理系统 效果如下&#xff1a; 系统首页界面 系统注册页面 剧本信息详细页面 后台登录界面 管理员主界面 剧本信息界面 剧本预约界面 作者主界面 研究背景 随着现代社会生活节奏的加快&#xff0c;人们越来越渴望通过各种娱乐活动来释放压力和增进社交…

开源 Three.js 案例及入门教程

Three.js入门教程目录 章节1认识three.js与开发环境搭建,rar 章节2 Three.js开发入门与调试设置,rar 章节3 Geometry进阶详解.rar 章节4 详解材质与纹理.rar 章节5 纹理材质高级操作,rar 章节6 详解灯光与阴影.rar 章节7 精通粒子特效.rar 章节8 详解光线投射与物体交互…

内容营销:基于大模型的内容再利用

在这篇文章中&#xff0c;我将带你了解一个完整的自动化系统&#xff0c;该系统可帮助你将任何内容重新用于你想要的其他帖子。 输入的内容可以是任何东西&#xff1a;YouTube 视频链接、博客文章链接、大纲、推文、pdf 等…… 我将在本文末尾为你提供所有代码。 一步一步地…

基于SpringBoot+Vue+Uniapp的仓库点单小程序的详细设计和实现

2. 详细视频演示 文章底部名片&#xff0c;联系我获取更详细的演示视频 3. 论文参考 4. 项目运行截图 代码运行效果图 代码运行效果图 代码运行效果图 代码运行效果图代码运行效果图 代码运行效果图 5. 技术框架 5.1 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发…

毕业设计 | Ruff开发板 + 华为云IoT物联网平台,实现家中温度、湿度、二氧化碳、PM2.5、甲醛监控分析...

基于温湿度、空气质量传感器实现温度、湿度、二氧化碳、PM2.5、甲醛环境数据实时监测。 硬件清单 我们采用 Ruff 开发板&#xff0c;串口连接温湿度传感器 DHT11 和空气质量传感器 SDS011&#xff0c;每5分钟采集一次数据&#xff0c;通过MQTT协议发送到华为云 IoT 物联网平台&…

QRTCN区间预测 | Matlab实现QRTCN时间卷积神经网络分位数回归区间预测

区间预测 | Matlab实现QRTCN时间卷积神经网络分位数回归区间预测 目录 区间预测 | Matlab实现QRTCN时间卷积神经网络分位数回归区间预测预测效果基本介绍模型特性程序设计参考资料预测效果 基本介绍 Matlab实现QRTCN时间卷积神经网络分位数回归区间预测 QRTCN(Quantile Regres…

Java数据类型常量

目录 一、数据类型 1.1分类 1.2关键字&内存占用&范围 1.3包装类 1.4说明 1.5类型转换 1.6类型提升 二、常量 2.1java中的常量 2.2定义常量 2.3分类 一、数据类型 1.1分类 1.2关键字&内存占用&范围 数据类型关键字内存占用范围字节型byte1字节-128…