[Algorithm][BFS][拓扑排序][课程表][课程表Ⅱ][火星词典] + BFS解决拓扑排序原理 详细讲解

目录

  • 0.原理讲解
    • 1.有向无环图
    • 2.AOV网
    • 3.拓扑排序
    • 4.实现拓扑排序
    • 5.如何建图?
  • 1.课程表
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 2.课程表 II
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 3.火星词典
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现


0.原理讲解

1.有向无环图

  • 有向无环图:DAG -> Directed Acyclic Graph

    • 入度:有多少条边指向它
    • 出度:有多少条从它出去
      请添加图片描述
  • 有向有环图

    • 结点4 5 6构成回路
      请添加图片描述

2.AOV网

  • 顶点活动图:AOV网 -> Activity on Vextex Network
    • :在有向无环图中,用顶点来表示一个活动,用来表示活动的先后顺序的图结构
    • :下图为做菜的流程图
      请添加图片描述

3.拓扑排序

  • 形象地说:找到做事情的先后顺序

  • 注意:拓扑排序的结果可能不是唯一的

  • 上图做菜的流程图中,可能会有下面两种排序结果

    准备厨具
    腌肉
    炒菜
    装盘
    干饭
    买菜
    洗菜
    切菜
    准备厨具
    腌肉
    炒菜
    装盘
    干饭
    买菜
    洗菜
    切菜
  • 如何排序?

    • 找出图中入度为0的点,然后输出
    • 删除与该点连接的边
    • 重复上述两步操作,直到图中没有点或者没有入度为0的点为止
  • 为什么判断条件是没有点 || 没有入度为0的点

    • 因为图中可能有环,是没办法到达没有点这个情况的
  • 拓扑排序重要应用:判断有向图中是否有环

4.实现拓扑排序

  • 借助队列,来一次BFS即可
  • 流程
    • 初始化:把所有入度为0的点加入到队列中
    • 当队列不为空的时候
      • 拿出队头元素,加入到最终结果中
      • 删除与该元素相连的边
      • 判断:与删除边相连的点,是否入度变成0
        • 如果入度为0,加入到队列中

5.如何建图?

  • 看稠密(数据量)选择合适的存储结构
    • 邻接矩阵
    • 邻接表
  • 邻接表除了用哈希桶存储外,也可以用以下容器抽象出来
    • vector<vector<int>> edges
      • 每个vector表示每个结点,vector里面的内容是其出度表
    • unordered_map<int, vector<int>> edges
      • int -> vector<int> == 当前结点 -> 出度表
      • 此处的元素类型是弹性的,此处的例子为int,若有需要string等其他类型也可以
    • unordered_map<char, unordered_set<char>> edges
    • 总结:根据具体元素,具体场景,灵活的使用容器即可
  • 根据算法流程,灵活建图
    • 每个结点的入度?
      • vector<int> in
      • 下标为对应结点,内容为对应入度
    • 每个结点的出度?
      • vector<int> out
      • 下标为对应结点,内容为对应出度
    • ……

1.课程表

1.题目链接

  • 课程表

2.算法原理详解

  • 本题问题可以转化为:
    • 能否拓扑排序?
    • 是否是有向无环图?/ 有向图中是否有环?
  • 本题建图实现unordered_map<int, vector<int>> edges

3.代码实现

bool CanFinish(int n, vector<vector<int>>& prerequisites) 
{unordered_map<int, vector<int>> edges; // 邻接表vector<int> in(n); // 存储每一个结点的入度// 1.建图for(auto& e : prerequisites){int a = e[0], b = e[1]; // b -> aedges[b].push_back(a); // 构建图的逻辑结构in[a]++; // 入度表}// 2.拓扑排序BFS// (1) 把所有入度为0的结点加入队列queue<int> q;for(int i = 0; i < n; i++){if(in[i] == 0){q.push(i);}}// (2) BFSwhile(q.size()){int tmp = q.front();q.pop();// 修改相连结点的边for(auto& e : edges[tmp]){in[e]--;if(in[e] == 0){q.push(e);}}}// 3.判断是否有环for(auto& e : in){if(e){return false;}}return true;
}

2.课程表 II

1.题目链接

  • 课程表 II

2.算法原理详解

  • 本题问题可以转化为:
    • 能否拓扑排序?
    • 是否是有向无环图?/ 有向图中是否有环?
  • 本题建图实现vector<vector<int>> edges

3.代码实现

vector<int> findOrder(int n, vector<vector<int>>& prerequisites) 
{vector<vector<int>> edges(n);vector<int> in(n);// 1.建图for(auto& v : prerequisites){int a = v[0], b = v[1]; // b -> aedges[b].push_back(a);in[a]++;}// 2.拓扑排序vector<int> ret;queue<int> q;// (1) 将所有入度为0的点入队列for(int i = 0 ; i < n; i++){if(in[i] == 0){q.push(i);}}// (2) BFSwhile(q.size()){int tmp = q.front();q.pop();ret.push_back(tmp);// 修改相连结点的边for(auto& e : edges[tmp]){in[e]--;if(in[e] == 0){q.push(e);}}}// 判断结果并返回if(ret.size() == n){return ret;}else{return {};}
}

3.火星词典

1.题目链接

  • 火星词典

2.算法原理详解

  • 本题问题可以转化为:
    • 能否拓扑排序?
    • 是否是有向无环图?/ 有向图中是否有环?
  • 如何搜索信息?
    • 两层for循环枚举出所有的两个字符串的组合
    • 利用双指针,根据字典序规则找出信息
  • 流程
    • 建图unordered_map<char, unordered_set<char>> edges
    • 统计入度信息unordered_map<char, int> in
      • 此哈希表必须要初始化,否则入度表里没有任何字符的信息,BFS时,无法将入度为0的结点入队列
    • 拓扑排序
  • 细节问题:类似abcab这两个字符串
    • 不管在哪儿,都应该是ab的字典序小于abc的字典序

3.代码实现

class Solution 
{unordered_map<char, unordered_set<char>> edges; // 邻接表unordered_map<char, int> in; // 入度表bool check = false; // 处理边界情况
public:string alienOrder(vector<string>& words) {// 1.初始化入度表for(auto& str : words){for(auto& ch : str){in[ch] = 0;}}// 2.枚举搜集字典信息 + 建图int n = words.size();for(int i = 0; i < n; i++){for(int j = i + 1; j < n; j++){AddInfo(words[i], words[j]);if(check){return "";}}}// 3. 拓扑排序string ret;queue<char> q;// (1) 入度为0的入队列for(auto& [ch, count] : in){if(count == 0){q.push(ch);}}// BFSwhile(q.size()){char tmp = q.front();q.pop();ret += tmp;// 修改相邻点的边for(auto& ch : edges[tmp]){if(--in[ch] == 0){q.push(ch);}}}// 检验是否有环for(auto& [ch, count] : in){if(count != 0){return "";}}return ret;}void AddInfo(const string& s1, const string& s2){int n = min(s1.size(), s2.size());int i = 0;while(i < n){if(s1[i] != s2[i]) {char a = s1[i], b = s2[i];// 避免数据冗余if(!edges.count(a) || !edges[a].count(b)){edges[a].insert(b);  // s1[i] -> s2[i]in[b]++;}break;}i++;}// 边界情况处理if(i == s2.size() && i < s1.size()){check = true;}}
};

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

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

相关文章

基于Django图像识别系统毕业设计(付源码)

前言&#xff1a;Django是一个由Python编写的具有完整架站能力的开源Web框架&#xff0c;Django本身基于MVC模型&#xff0c;即Model&#xff08;模型&#xff09;View&#xff08;视图&#xff09; Controller&#xff08;控制器&#xff09;设计模式&#xff0c;因此天然具有…

【抽样调查】分层抽样上

碎碎念&#xff1a;在大一大二时听课有的时候会发现听不太懂&#xff0c;那时候只觉得是我自己的基础不好的原因&#xff0c;但现在我发现“听不懂”是能够针对性解决的。比如抽样调查这门课&#xff0c;分析过后我发现我听不懂的原因之一是“没有框架”&#xff0c;一大堆知识…

【使用ChatGPT的API之前】OpenAI API提供的可用模型

文章目录 一. ChatGPT基本概念二. OpenAI API提供的可用模型1. InstructGPT2. ChatGPT3. GPT-4 三. 在OpenAI Playground中使用GPT模型-ing 在使用GPT-4和ChatGPT的API集成到Python应用程序之前&#xff0c;我们先了解ChatGPT的基本概念&#xff0c;与OpenAI API提供的可用模型…

情感分类学习笔记(1)

文本情感分类&#xff08;二&#xff09;&#xff1a;深度学习模型 - 科学空间|Scientific Spaces 一、代码理解 cw lambda x: list(jieba.cut(x)) #定义分词函数 您给出的代码定义了一个使用 jieba 分词库的分词函数。jieba 是一个用于中文分词的 Python 库。该函数 cw 是…

FTTR介绍

概念 FTTR&#xff08;Fiber to The Room&#xff09;是一种新型的光纤接入技术&#xff0c;它将光纤信号传输到室内的一个通信网络方案。在FTTR网络中&#xff0c;光纤到达建筑物内的分配盒后&#xff0c;通过铜缆或其他传输介质进入室内各个房间&#xff0c;为用户提供网络服…

Java面试八股文(SpringCloud篇)

****************************************************

前端双语实现方案(VUE版)

一、封装一个lib包 结构如下 en.js use strict;exports.__esModule true; exports.default {sp: {input: {amountError: Incorrect amount format},table: {total: Total:,selected: Selected:,tableNoData: No data,tableNoDataSubtext: Tip: Suggest to recheck your fil…

使用css的box-reflect属性制作倒影效果

box-reflect 是一个在 CSS 中创建元素倒影效果的非标准属性。尽管它在过去的一些 WebKit 浏览器中&#xff08;如旧版的 Safari 和 Chrome&#xff09;得到了支持&#xff0c;但由于它并未成为 CSS 标准的一部分&#xff0c;因此在现代浏览器中的兼容性较差。以下是对 box-refl…

瑞麦德机电设备有限公司将莅临2024第13届生物发酵展

参展企业介绍 河南瑞麦德机电设备有限公司是专业从事机械输送气力输送、称重配料、筛分、磁选设备研发和制造于一体的企业&#xff0c;公司采用国内外同行业产品的先进技术&#xff0c;经专业团队设计、研发、生产&#xff0c;产品满足“ISO9001”&#xff0c;“GMP”等标准要求…

【BST】Behavior Sequence Transformer for E-commerceRecommendation in Alibaba

一、提出背景 传统的Embedding&MLP模型结构将原始特征嵌入到低维向量中&#xff0c;然后将其concat后输入MLP进行最终推荐。DIN提出使用注意力机制来捕获候选项与用户先前点击的项之间的相似性。 然而&#xff0c;大多数这些工作只是连接不同的特征&#xff0c;而没有捕获用…

云动态摘要 2024-05-08

给您带来云厂商的最新动态&#xff0c;最新产品资讯和最新优惠更新。 最新优惠与活动 [免费试用]即刻畅享自研SaaS产品 腾讯云 2024-04-25 涵盖办公协同、营销拓客、上云安全保障、数据分析处理等多场景 云服务器ECS试用产品续用 阿里云 2024-04-14 云服务器ECS试用产品续用…

通过自适应提示提升大语言模型的零样本推理能力

随着大模型&#xff08;LLMs&#xff09;的快速发展&#xff0c;它们在自然语言处理&#xff08;NLP&#xff09;任务上取得了前所未有的成就。特别是&#xff0c;LLMs展现出了强大的推理和规划能力&#xff0c;这得益于它们的少样本和零样本学习能力。然而&#xff0c;现有的方…

spring模块(六)spring监听器(2)@EventListener

一、介绍 监听器的简化写法 二、原理 三、使用 Slf4j Component public class MyTask {EventListenerpublic void onApplicationEvent(ApplicationEvent event) {if (event instanceof ContextRefreshedEvent) {log.info("监听到 ContextRefreshedEvent...");}if…

Seata之XA 模式的使用

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 Seata 是一款开源的…

全网最全:一文入门最热的LLM应用开发框架LangChain

f#### 1. LangChain 简介 1.1. LangChain 发展史 LangChain 的作者是 Harrison Chase&#xff0c;最初是于 2022 年 10 月开源的一个项目&#xff0c;在 GitHub 上获得大量关注之后迅速转变为一家初创公司。2017 年 Harrison Chase 还在哈佛上大学&#xff0c;如今已是硅谷的…

CPU基本知识点

目录 1.概念 2.分类 3.运作原理 4.指令系统 1.概念 CPU&#xff1a;英文Central Processing Unit&#xff0c;即中央处理器。 解释和执行指令的功能单元&#xff0c;它是计算机的中枢神经系统&#xff08;即核心&#xff09;。 是计算机最核心的部件&#xff0c;主要是运算…

大家都是怎么写毕业论文的? 推荐4个AI工具

写作这件事一直让我们从小学时期就开始头痛&#xff0c;初高中时期800字的作文让我们焦头烂额&#xff0c;一篇作文里用尽了口水话&#xff0c;拼拼凑凑才勉强完成。 大学时期以为可以轻松顺利毕业&#xff0c;结果毕业前的最后一道坎拦住我们的是毕业论文&#xff0c;这玩意不…

Java中包的概念package

Package Package:包 指明方法、类所处的包&#xff1b; 将类分配到不同的包中&#xff0c;方便管理&#xff1b; 用于指明文件中定义的类、接口等结构所在的包&#xff1b; 一个源文件只要一个包的声明语句&#xff0c;必须放到开头&#xff1b; 属于标识符&#xff0c;满足命…

细说夜莺监控系统告警自愈机制

虽说监控系统最侧重的功能是指标采集、存储、分析、告警&#xff0c;为了能够快速恢复故障&#xff0c;告警自愈机制也是需要重点投入建设的&#xff0c;所有可以固化为脚本的应急预案都可以使用告警自愈机制来快速驱动。夜莺开源项目从 v7 版本开始内置了告警自愈模块&#xf…

blender导出gltf模型混乱

最近用户给了几个blender文件&#xff0c;在blender打开是这样的&#xff1a; 我导出成gltf候&#xff0c;在本地打开时&#xff0c;底部发生了改变&#xff1a; 可以看出来&#xff0c;底部由原来的类型box变为了两个平面&#xff0c;后来我查了下blender里的属性设置&#xf…