BFS算法篇——打开智慧之门,BFS算法在拓扑排序中的诗意探索(下)

文章目录

  • 引言
  • 一、课程表
    • 1.1 题目链接:https://leetcode.cn/problems/course-schedule/description/
    • 1.2 题目分析:
    • 1.3 思路讲解:
    • 1.4 代码实现:
  • 二、课程表||
    • 2.1 题目链接:https://leetcode.cn/problems/course-schedule-ii/description/
    • 2.2 题目分析:
    • 2.3 思路讲解:
    • 2.4 代码实现:
  • 三、火星词典
    • 3.1 题目链接:https://leetcode.cn/problems/Jf1JuT/description/
    • 3.2 题目分析:
    • 3.3 思路讲解:
    • 3.4 代码实现:
  • 小结

在这里插入图片描述

引言

上篇我们介绍了BFS解决拓扑排序的背景知识,本篇我们将结合具体题目分析,进一步深化对于该算法的理解运用。

一、课程表

1.1 题目链接:https://leetcode.cn/problems/course-schedule/description/

1.2 题目分析:

  • numCourses 表示要学的课程的数量
  • prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。
  • 如果存在能按照顺序学完的可能,返回true,否则返回false

1.3 思路讲解:

该题为一个明显的拓扑排序问题,根据上篇讲解,我们可以这样子处理

  • 首先构建邻接表,先决条件pre表示的顺序即为b->a,作为边加入其中
  • 同时,由于学习a之前必须要学习b,因此a的入度加1
  • 之后将入度为0的节点入队列,层序遍历即可

1.4 代码实现:

class Solution {
public:bool canFinish(int n, vector<vector<int>>& prerequisites) {unordered_map<int,vector<int>> edges;//邻接表vector<int> in(n);//入度//建图for(auto e: prerequisites){int a=e[0],b=e[1];edges[b].push_back(a);in[a]++;}queue<int> q;//将入度为0的节点入队列for(int i=0;i<n;i++){if(in[i]==0){q.push(i);}}//层序遍历while(q.size()){int t=q.front();q.pop();for(int e : edges[t]){in[e]--;if(in[e]==0){q.push(e);}}}for(int i=0;i<n;i++){if(in[i]){return false;}//说明无法学完所有课程}return true;}
};

二、课程表||

2.1 题目链接:https://leetcode.cn/problems/course-schedule-ii/description/

2.2 题目分析:

该题与上题要求基本相同,只是返回值要求返回可能的一种学习顺序,如果不存在,则返回空数组

2.3 思路讲解:

判断是否可以学习的思路与上题相同,我们只需要在层序遍历时,用一个数组记录当前学习顺序即可。

2.4 代码实现:

class Solution {
public:vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {unordered_map<int,vector<int>> edges;//邻接表vector<int> in(numCourses);//入度vector<int> ret;//返回值vector<int> temp;//空数组queue<int> q;//建图for(auto e:prerequisites){int a=e[0],b=e[1];edges[b].push_back(a);in[a]++;}//入度为0的节点入队列for(int i=0;i<numCourses;i++){if(in[i]==0){q.push(i);}}while(q.size()){int t=q.front();q.pop();ret.push_back(t);//更新结果for(int e:edges[t]){in[e]--;if(in[e]==0){q.push(e);}}}for(int i=0;i<numCourses;i++){if(in[i]){return temp;}}//存在未完成情况,返回空数组return ret;}
};

三、火星词典

3.1 题目链接:https://leetcode.cn/problems/Jf1JuT/description/

3.2 题目分析:

题目要求一时间难以读懂,我们来简单翻译一下:

  • 给定的word里面已经按一种新的字母顺序排列好

假设 words = [“wrt”,“wrf”,“er”,“ett”,“rftt”],我们可以得到字母之间的一些依赖关系:

  • 比如从 “wrt” 和 “wrf” 可以得出 t 在 f 之前(因为 “t” 是两个单词中的不同字母,且在相同位置上不同)。

  • 从 “er” 和 “ett” 中可以得出 r 在 e 之前。

最终需要返回题目中外星词典的递增顺序,若不存在合法的顺序,则返回空

3.3 思路讲解:

我们通过比较相邻的单词,找出它们的第一个不同字母。这些字母的顺序关系就可以帮助我们构建字母的顺序图。

图的构建:

  • 我们可以通过图来表示字母之间的顺序关系。每个字母是图中的一个节点,而字母之间的顺序关系是边。

拓扑排序:

  • 通过拓扑排序的方法,我们可以得到字母的正确排序。如果有环,则说明字母顺序无法确定,返回空字符串。

3.4 代码实现:

class Solution {
public:unordered_map<char,unordered_set<char>> edges;//边unordered_map<char,int> in;//入度bool check;//处理特殊情况void add(string& s1,string& s2){int n=min(s1.size(),s2.size());int i;for( i=0;i<n;i++){if(s1[i]!=s2[i]){char a=s1[i],b=s2[i];if(!edges.count(a) || !edges[a].count(b))//如果之前为记录过,则记录这条边a->b{edges[a].insert(b);in[b]++;//更新边和入度节点}break;//注意跳出循环}}if(i==s2.size()&&i<s1.size())//处理abc ab这种特殊情况{check=true;}}string alienOrder(vector<string>& words) {//建图和初始化for(auto e: words){for(auto ch:e){in[ch]=0;}//将所有字符的入度都初始化为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 "";//存在非法情况}}}//拓扑排序queue<char> q;string ret;//将所有入度为0的节点for(auto [a,b] :in){if(b==0){q.push(a);}}while(q.size()){char t=q.front();q.pop();ret+=t;for(auto e:edges[t]){if(--in[e]==0) q.push(e);}}for(auto [a,b] :in){if(b!=0){return "";}}//判断是否存在不合法顺序return ret;}
};

小结

本篇关于BFS解决拓扑排序的讲解就暂告段落啦,希望能对大家的学习产生帮助,欢迎各位佬前来支持斧正!!!

在这里插入图片描述

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

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

相关文章

计数循环java

import java.util.Scanner;public class Hello {public static void main(String[] args) {Scanner in new Scanner(System.in);int count 10;while(count > 0) {count count -1;System.out.println(count);}System.out.println(count);System.out.println("发射&am…

11. CSS从基础样式到盒模型与形状绘制

在前端开发中&#xff0c;CSS&#xff08;层叠样式表&#xff09;是控制网页样式和布局的核心技术。整理了关于 CSS 基础样式、文本样式、盒模型以及形状绘制的一些心得。以下是详细的学习笔记。 一、基础样式设置 1. 字体样式 字体样式是网页视觉呈现的重要组成部分&#xf…

双种群进化算法:动态约束处理与资源分配解决约束多目标优化问题

双种群进化算法&#xff1a;动态约束处理与资源分配解决约束多目标优化问题 一、引言 约束多目标优化问题&#xff08;CMOPs&#xff09;在工程设计、资源分配等领域广泛存在&#xff0c;其核心是在满足多个约束条件的同时优化多个目标函数。传统方法往往难以平衡约束满足与目…

【Qt】pro工程文件转CMakeLists文件

1、简述 Qt6以后默认使用cmake来管理工程,之前已经一直习惯使用pro,pro的语法确实很简单、方便。 很多项目都是cmake来管理,将它们加入到Qt项目中,cmake确实是大势所趋。比如,最近将要开发的ROS项目,也是使用的cmake语法。 以前总结的一些Qt代码,已经编写成pro、pri等…

手机换地方ip地址会变化吗?深入解析

在移动互联网时代&#xff0c;我们经常带着手机穿梭于不同地点&#xff0c;无论是出差旅行还是日常通勤。许多用户都好奇&#xff1a;当手机更换使用地点时&#xff0c;IP地址会随之改变吗&#xff1f;本文将深入解析手机IP地址的变化机制&#xff0c;帮助您全面了解这一常见但…

【Canda】常用命令+虚拟环境创建到选择

目录 一、conda常用命令 二、conda 环境 2.1 创建虚拟环境 2.2 conda环境切换 2.3 查看conda环境 2.4 删除某个conda环境 2.5 克隆环境 三、依赖包管理 3.1 安装命令 3.2 更新包 3.3 卸载包 3.4 查看环境中所有包 3.5 查看某个包的版本信息 3.6 搜索包 四、环境…

目标检测任务常用脚本1——将YOLO格式的数据集转换成VOC格式的数据集

在目标检测任务中&#xff0c;不同框架使用的标注格式各不相同。常见的框架中&#xff0c;YOLO 使用 .txt 文件进行标注&#xff0c;而 PASCAL VOC 则使用 .xml 文件。如果你需要将一个 YOLO 格式的数据集转换为 VOC 格式以便适配其他模型&#xff0c;本文提供了一个结构清晰、…

Python作业练习2

任务简述 if_name__main_的含义&#xff0c;why? 问题解答 在Python中&#xff0c;if __name__ __main__:是一种常见的惯用法&#xff0c;用于检查当前模块是否是主程序入口点。要理解其含义和用途&#xff0c;首先需要了解两个概念&#xff1a; 1. __name__: 这是一个特…

ppy/osu构建

下载 .NET (Linux、macOS 和 Windows) | .NET dotnet还行 构建&#xff1a;f5 运行&#xff1a;dotnet run --project osu.Desktop -c Debug

NY182NY183美光固态颗粒NY186NY188

NY182NY183美光固态颗粒NY186NY188 在存储技术的竞技场上&#xff0c;美光科技&#xff08;Micron&#xff09;始终扮演着革新者的角色。其NY系列固态颗粒凭借前沿的3D NAND架构和精准的工艺控制&#xff0c;成为企业级存储和数据中心的关键支柱。本文将围绕NY182、NY183、NY1…

C++的历史与发展

目录 一、C 的诞生与早期发展 &#xff08;一&#xff09;C 语言的兴起与局限 &#xff08;二&#xff09;C 的雏形&#xff1a;C with Classes &#xff08;三&#xff09;C 命名与早期特性丰富 二、C 的主要发展历程 &#xff08;一&#xff09;1985 年&#xff1a;经典…

DedeCMS-Develop-5.8.1.13-referer命令注入研究分析 CVE-2024-0002

本次文章给大家带来代码审计漏洞挖掘的思路&#xff0c;从已知可控变量出发或从函数功能可能照成的隐患出发&#xff0c;追踪参数调用及过滤。最终完成代码的隐患漏洞利用过程。 代码审计挖掘思路 首先flink.php文件的代码执行逻辑&#xff0c;可以使用php的调试功能辅助审计 …

计算机网络|| 常用网络命令的作用及工作原理

1.hostname 作用&#xff1a;显示计算机的完整计算机名的主机名部分。仅当 Internet 协议 (TCP/IP) 协议作为组件安装在网络的网络适配器的属性中时&#xff0c;此命令才可用。 2.ping 作用&#xff1a; 1.用来检测网络的连通情况和分析网络速度 2.根据域名得到服务器 IP …

用户态到内核态:Linux信号传递的九重门(二)

1. 保存信号 1.1. 信号其他相关常见概念 实际执⾏信号的处理动作称为信号递达(Delivery)。 信号从产⽣到递达之间的状态,称为信号未决(Pending)。 进程可以选择阻塞 (Block )某个信号。 被阻塞的信号产⽣时将保持在未决状态,直到进程解除对此信号的阻塞,才执⾏递达的动作。 1.…

tar -zxvf jdk-8u212-linux-x64.tar.gz -C /opt/module/这个代码的解释

tar -zxvf jdk-8u212-linux-x64.tar.gz -C /opt/module/ 这条命令的解释如下&#xff1a; 1. tar&#xff1a;这是 Linux 系统中用于归档和压缩文件的命令行工具。 2. -z&#xff1a;表示通过 gzip 压缩格式来处理文件&#xff0c;因为文件 jdk-8u212-linux-x64.tar.gz 是一个经…

SysAid On-Prem XML注入漏洞复现(CVE-2025-2776)

免责申明: 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 前…

Nginx的增强与可视化!OpenResty Manager - 现代化UI+高性能反向代理+安全防护

以下是对OpenResty Manager的简要介绍&#xff1a; OpenResty Manager &#xff08;Nginx 增强版&#xff09;&#xff0c;是一款容易使用、功能强大且美观的反向代理工具 &#xff0c;可以作为OpenResty Edge 的开源替代品基于 OpenResty 开发&#xff0c;支持并继承 OpenRes…

旅游推荐数据分析可视化系统——讯飞AI助手(超级v2版本)+论文+数据+源码

旅游推荐数据分析可视化系统——讯飞AI助手(超级v2版本)论文数据源码 项目介绍 本项目是一个基于Django框架开发的旅游推荐数据分析可视化系统&#xff0c;集成了讯飞AI大模型助手功能。系统通过对去哪儿网的旅游数据进行采集、分析和可视化&#xff0c;为用户提供个性化的旅…

大疆无人机(全系列,包括mini)拉流至电脑,实现直播

参考视频 【保姆级教程】大疆无人机rtmp推流直播教程_哔哩哔哩_bilibili VLC使用教程&#xff1a; VLC工具使用指南-CSDN博客 目录 实现效果&#xff1a; 电脑端 ​编辑 ​编辑 无人机端 VLC拉流 分析 实现效果&#xff1a; (实验机型&#xff1a;大疆mini4kRC-N2遥控器、大…

windows系统使用phpstudy安装ssl证书

一、证书准备与上传 获取证书文件‌ 免费证书&#xff08;如阿里云、Lets Encrypt&#xff09;&#xff1a;下载包含.crt&#xff08;证书&#xff09;、.key&#xff08;私钥&#xff09;、chain.crt&#xff08;证书链&#xff09;的文件包 自签名证书&#xff08;测试用&a…