【深度优先搜索】【图论】【推荐】332. 重新安排行程

作者推荐

动态规划的时间复杂度优化

本文涉及知识点

深度优先搜索 图论

LeetCode332. 重新安排行程

给你一份航线列表 tickets ,其中 tickets[i] = [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。
所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 开始。如果存在多种有效的行程,请你按字典排序返回最小的行程组合。
例如,行程 [“JFK”, “LGA”] 与 [“JFK”, “LGB”] 相比就更小,排序更靠前。
假定所有机票至少存在一种合理的行程。且所有的机票 必须都用一次 且 只能用一次。

示例 1:
在这里插入图片描述

输入:tickets = [[“MUC”,“LHR”],[“JFK”,“MUC”],[“SFO”,“SJC”],[“LHR”,“SFO”]]
输出:[“JFK”,“MUC”,“LHR”,“SFO”,“SJC”]
示例 2:
在这里插入图片描述

输入:tickets = [[“JFK”,“SFO”],[“JFK”,“ATL”],[“SFO”,“ATL”],[“ATL”,“JFK”],[“ATL”,“SFO”]]
输出:[“JFK”,“ATL”,“JFK”,“SFO”,“ATL”,“SFO”]
解释:另一种有效的行程是 [“JFK”,“SFO”,“ATL”,“JFK”,“ATL”,“SFO”] ,但是它字典排序更大更靠后。

提示:
1 <= tickets.length <= 300
tickets[i].length == 2
fromi.length == 3
toi.length == 3
fromi 和 toi 由大写英文字母组成
fromi != toi

基础知识

定义

如果图G中的一个路径包括每个边恰好一次,则该路径称为欧拉路径(Euler path)。
如果一个回路是欧拉路径,则称为欧拉回路(Euler circuit)。

性质

性质一:一个有向图是欧拉回路 ⟺ \iff 所有顶点的入度等于出度且该图是连通图。
性质二:一个有向图是欧拉路径 ⟺ \iff 起点出度等于入度+1,终点入度=出度+1,其它顶点的入度等于出度且该图是连通图。
欧拉路径和回路符合性质比较简单,不证明。下面只证明性质一必定是欧拉回路,性质二是欧拉路径。

证明一

设有向图G符合性质一。
操作一:以任意定点为起点s,选取s的任意临接点n1,删除sn1后,除s外,其它顶点都是出度等于入度,就是进入后,一定会离开。由于顶点的出度和入度是有限的,所以一定会结束,而结束点一定是s(因为只有它入度大于出度)。设删除经过的路径为P1。
最后一次经过s后,可能有些点入度并不为0。
→ { ∗ ∗ 操作二 ∗ ∗ 图 G 删除 P 1 各边,此时余下的边 P 2 仍然符合性质一。 P 1 经过的各点,一定有点 n 2 出度不为 0 。否则与连通图矛盾。 \rightarrow\begin{cases}**操作二**图G删除P1各边,此时余下的边P2仍然符合性质一。\\ P1经过的各点,一定有点n2出度不为0。否则与连通图矛盾。\\ \end{cases} {操作二G删除P1各边,此时余下的边P2仍然符合性质一。P1经过的各点,一定有点n2出度不为0。否则与连通图矛盾。
操作二时:如果有重边,经过几次则删除几条。
以n2为起点对P2进行操作一,得到P3,必定以n2开始和结尾。
用P3替换P1的n2节点。如此往复直到所有节点出度入度为0。

证明二

设有向图G符合性质二,s出度=入度+1,e入度=出度+1。一定存在以s为起点,e为终点的路径P1。选取方法类似证明一,多个出边任选一条出边。图G删除P1后,为P2;P2要么为空,要么符合性质二。

深度优先搜索

题目确保某条从JFK为起点的路径是欧拉路径。
如果是欧拉环路:所有点出度等于入度。
如果不是环路:起点出度-1==入度 终点入度=出度+1,其它节点入度等于出度。
必须确保起点最后访问终点那一支,其它访问顺序按字典需。

DFS 函数

在这里插入图片描述

主函数

DFS(“JFK”)
颠倒m_vRes的顺序
返回m_vRet。

示例和时序图

在这里插入图片描述
在这里插入图片描述

按时间线访问m_vRes的顺序:DAFEACBA。转置(颠倒顺序)后为:ABCAEFAD。

证明:

假定图G的欧拉路径最后一个出度大于1的节点为c,它共有m+1+n条出边,按邻接字典序排序后,第m+1条出边指向终点e。
步骤一:只讨论节点c及之后的路径。设c的临接点按字典序分别为:n[1] …n[m+n+1]。
除DFS(n[1+m] → \rightarrow e)可以直接结束,其它节点都必须等所有A的出边都访问结束(包括n[1+m]),所以 n[1+m] → \rightarrow e 的逆序最先加到vRet。
c → \rightarrow n[n+m+1]是c最后一条出边,故将 n[i+m+1] → \rightarrow c 的逆序放到vRet 中。
c → \rightarrow n[n+m ]是c最倒数第二条出边,故将 n[i+m] → \rightarrow c 的逆序放到vRet 中。
⋯ \cdots 将 n[1+m+1] → \rightarrow c 的逆序放到vRet 中。
⋮ \vdots
⋯ \cdots 将 n[m] → \rightarrow c 的逆序放到vRet 中。
⋯ \cdots n[1 ] → \rightarrow c 的逆序放到vRet 中。
将c 放到vRet 中。
步骤二:将图G 节点c及之后节点的出边都删除。c变成新的终点。
不断持续步骤一二到所有节点的出度为1。注意:c等于e也符合。

代码

核心代码

class Solution {
public:vector<string> findItinerary(vector<vector<string>>& tickets) {std::unordered_map<string, multiset<string>> mNeiBo;for (const auto& v : tickets){mNeiBo[v[0]].emplace(v[1]);}DFS(mNeiBo, "JFK");std::reverse(m_vRet.begin(), m_vRet.end());return m_vRet;}void DFS(std::unordered_map<string, multiset<string>>& mNeiBo,const string& cur){while (mNeiBo[cur].size()){auto next = *mNeiBo[cur].begin();mNeiBo[cur].erase(mNeiBo[cur].begin());DFS(mNeiBo, next);}m_vRet.emplace_back(cur);}vector<string> m_vRet;
};

测试用例

template<class T,class T2>
void Assert(const T& t1, const T2& t2)
{assert(t1 == t2);
}template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}}int main()
{vector<vector<string>> tickets;{Solution sln;tickets = { {"MUC","LHR"},{"JFK","MUC"},{"SFO","SJC"},{"LHR","SFO"} };auto res = sln.findItinerary(tickets);Assert({ "JFK","MUC","LHR","SFO","SJC" }, res);}{Solution sln;tickets = { {"JFK","SFO"},{"JFK","ATL"},{"SFO","ATL"},{"ATL","JFK"},{"ATL","SFO"} };auto res = sln.findItinerary(tickets);Assert({ "JFK","ATL","JFK","SFO","ATL","SFO" }, res);}
}

2023年4月

class Solution {
public:vector<string> findItinerary(vector<vector<string>>& tickets) {		for (const auto& v : tickets){m_vNeiB[v[0]].emplace(v[1]);}dfs("JFK");std::reverse(m_vRet.begin(), m_vRet.end());return m_vRet;}void dfs(const string& sCur){while (m_vNeiB.count(sCur) && m_vNeiB[sCur].size()){const string sNext = m_vNeiB[sCur].top();m_vNeiB[sCur].pop();dfs(sNext);}m_vRet.emplace_back(sCur);}std::unordered_map < string, std::priority_queue<string, vector<string>, greater<string>>> m_vNeiB;vector<string> m_vRet;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关

下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

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

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

相关文章

correlated double sampling (CDS)相关双采样

目录 原理内部电路和时序使用时注意事项1.内部电路非匹配2.时序要求精确 学习资料 原理 correlated double sampling (CDS)相关双采样&#xff0c;主要用在图像传感器image sensor CMOS和CCD中。 处理流程如下&#xff1a; 采集复位信号采集真正的信号真正的信号-复位信号实…

AI时代的产品文案秘籍:如何用AI提升效率

人工智能写作工具&#xff1a;解放双手&#xff0c;创作不停歇 在当前人工智能技术飞速发展的背景下&#xff0c;越来越多的个体已经开始利用这一AI写作工具&#xff0c;以显著提高自己的工作效率。这不仅标志着人工智能服务于人类的宏伟时代的到来&#xff0c;更是人人可用的创…

深度学习--神经网络基础

神经网络 人工神经网络&#xff08; Artificial Neural Network &#xff0c; 简写为 ANN &#xff09;也简称为神经网络&#xff08; NN &#xff09;&#xff0c;是一种模仿生物神经网络结构和 功能的计算模型 。人脑可以看做是一个生物神经网络&#xff0c;由众多的 神经元…

Sectigo SSL证书有什么优势?

在全球范围内&#xff0c;Sectigo作为一家备受信赖的数字证书颁发机构&#xff0c;以其强大的安全性、出色的性价比和卓越的品牌形象赢得了广大用户的青睐。本文将深入剖析Sectigo SSL证书在这些方面的卓越表现。 一、安全性 1. 强大加密技术 Sectigo SSL证书采用行业标准的加…

高校水电预付费管控系统

高校水电预付费管控系统在现代高校管理中扮演着重要角色。这一系统通过整合先进的科技手段&#xff0c;如智能计量设备和互联网技术&#xff0c;实现对校园水电消费的精准监控和管理。首先&#xff0c;高校水电预付费管控系统能够有效监测学生宿舍、教学楼等区域的实时用水用电…

Java实战:构建高效预报名管理系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

单/双通道40V 350mA车规级LDO稳压器高集成电流感应调节

概述 PC8803具有高输入电压单低压差调节器&#xff08;PC8803SC01/PC8803SCO3&#xff09;/双通道低压差调节&#xff08;PC8803SC02/PC8803SC04&#xff09;&#xff0c;具有精确的电流感测&#xff0c;设计用于在宽输入电压范围内工作 从4.5V到40V。该设备具有45V负载转储电…

Redis String 类型底层揭秘

目录 前言 String 类型低层数据结构 节省内存的数据结构 前言 Redis 的 string 是个 “万金油” &#xff0c;这么评价它不为过. 它可以保存Long 类型整数&#xff0c;字符串&#xff0c; 甚至二进制也可以保存。对于key&#xff0c;value 这样的单值&#xff0c;查询以及插…

【C++】结构体内存对齐详解

规则 1.第一个成员在结构体变量偏移量为0 的地址处&#xff0c;也就是第一个成员必须从头开始。 2.其他成员的偏移量为对齐数**(该成员的大小 与 编译器默认的一个对齐数 中的较小值)**的整数倍。 3.结构体总大小对最大对齐数&#xff08;通过最大成员来确定&#xff09;的整数…

Oracle 直接路径插入(Direct-Path Insert)

直接路径插入&#xff08;Direct Path Insert&#xff09;是Oracle一种数据加载提速技术&#xff0c;可以在使用insert语句或SQL*Loader工具大批量加载数据时使用。直接路径插入处理策略与普通insert语句完全不同&#xff0c;Oracle会通过牺牲空间&#xff0c;安全性&#xff0…

opengles 绘制图元 ——glDrawArrays() 相关API介绍 (十)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、opengles3.0 绘制图元介绍二、绘图图元 API 介绍1. glDrawArrays()1.1 glDrawArrays()函数原型1.2 GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN 三者的区别1.3 使用GL_TRIANGLES, G…

springboot+maven项目导入本地jar包,以有打包错误问题

1 本地jar包放置路径为&#xff1a; 2添加Modules File->project settings–>Modules–>Dependencies–>–>, 3 添加 Libraies 至此 项目即可成功运行。 mvn 打包错误&#xff0c;需要 运行以下命令 mvn install:install-file -Dfile${project.basedir}/s…

52.2k star! 自己部署gpt4free, 免费使用各种GPT

GPT4Free是一个由开发者Xtekky在GitHub上发布的开源项目&#xff0c;它可以免费地使用GPT-3.5、GPT-4、llama、gemini-pro、bard、claude等多种大模型。截止到当前(2024.1.30)已经有52.2k star&#xff0c;可见其受欢迎程度。 github地址&#xff1a;https://github.com/xtekky…

拜登:“一切非 Rust 项目均为非法”,开发界要大变天?

文章目录 科技巨头应为安全漏洞负起责任使用其他语言的开发者​该何去何从&#xff1f; 白宫国家网络总监办公室&#xff08;ONCD&#xff0c;以下简称网总办&#xff09;在本周一发布的报告中说道&#xff1a;“程序员编写代码并非没有后果&#xff0c;他们的⼯作⽅式于国家利…

Leetcode 134. 加油站 java版 如何解决环路加油站算法

# 官网链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 1. 问题描述&#xff1a; 在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升…

C语言之操作符详解

文章目录 一、算术操作符二、移位操作符1、 原码、反码、补码2、左移操作符3、右移操作符 三、位操作符1、按位与【&】2、按位或【|】3、按位异或【^】4、按位取反【~】5、两道面试题6、进制定位将变量a的第n位置为1将变量a的第n位置为0 四、赋值操作符1、复合赋值符 五、单…

Linux系统---nginx(4)负载均衡

目录 1、服务器配置指令 ​编辑 1.1 服务器指令表 1.2 服务器指令参数 2、负载均衡策略指令 2.1 轮询 &#xff08;1) 加权轮询 &#xff08;2) 平滑轮询 2.2 URL 哈希&#xff08;一致性哈希&#xff09; 2.3 IP哈希策略 2.4 最少连接 Nginx 负载均衡是由代理模块和上…

【STM32】STM32学习笔记-WDG看门狗(46)

00. 目录 文章目录 00. 目录01. WDG简介02. IWDG概述03. IWDG框图04. IWDG键寄存器05. WWDG简介06. WWDG框图07. WWDG工作特性08. IWDG和WWDG对比09. 预留10. 附录 01. WDG简介 WDG&#xff08;Watchdog&#xff09;看门狗 看门狗可以监控程序的运行状态&#xff0c;当程序因为…

嵌入式烧录报错:板端IP与PC的IP相同

报错&#xff1a; 配置 实际上我配置并没有错。 服务器IP&#xff08;就是本机&#xff09;、板端IP、网关。此处网关必须与板子IP配套&#xff08;可以不存在&#xff09;。 解决 我网卡配置了多个IP。一番删除添加还是报错。 于是点击服务器IP&#xff0c;换成别的&#x…

鸿蒙OS应用编程实战:构建未来应用的基石

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 引言 鸿蒙OS&#xff08;HarmonyOS&#xff0…