【LeetCode】332. Reconstruct Itinerary 解题报告(Python)
作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
题目地址:https://leetcode.com/problems/reconstruct-itinerary/description/
题目描述
Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], reconstruct the itinerary in order. All of the tickets belong to a man who departs from JFK. Thus, the itinerary must begin with JFK.
Note:
If there are multiple valid itineraries, you should return the itinerary that has the smallest lexical order when read as a single string. For example, the itinerary ["JFK", "LGA"] has a smaller lexical order than ["JFK", "LGB"].
All airports are represented by three capital letters (IATA code).
You may assume all tickets form at least one valid itinerary.
Example 1:
Input: [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]]
Output: ["JFK", "MUC", "LHR", "SFO", "SJC"]
Example 2:
Input: [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]
Output: ["JFK","ATL","JFK","SFO","ATL","SFO"]
Explanation: Another possible reconstruction is ["JFK","SFO","ATL","JFK","ATL","SFO"].
But it is larger in lexical order.
题目大意
重新安排行程,使得给出的所有航班都得经过一次。如果出现多条可行的路径,那么优先选择的字典序最小的航班路径。出发点一定是JFK,而且题目保证了最少有一个可行的遍历路径。
解题方法
后序遍历
感觉是我自己太菜鸡了,看到花花神一般的解法,感觉自己永远不可能想出来的。
这道题的本质是计算一个最"小"的欧拉路径(Eulerian path)。对于一个节点(当然先从JFK开始),贪心地访问最小的邻居,访问过的边全部删除。当碰到死路的时候就回溯到最近一个还有出路的节点,然后把回溯的路径放到最后去访问,这个过程和后序遍历的一样。1. 如果子节点没有死路(每个节点都只左子树),前序遍历便是欧拉路径。2. 如果子节点1是死路,子节点2完成了遍历,那么子节点2先要被访问。1,2都和后序遍历的顺序正好相反。
其中,如果碰到死路,而没有把所有的边都走过一遍的话,就说明这种走法不满足itinerary,需要沿着树根向上找到最近的一个有其他路可以走的节点N,把新的路走一遍。因为题目保证一定存在一条满足要求的itinerary路径,那么一条这样的死路,一定会相对的在这个节点N上存在另一条路,这条路存在一个回到该节点N的环。先把这个环走过之后再去走这条死路,就可以保证把以N为树根的这个路径上的所有点都走到。
首先肯定是要把路径保存成链表法表示的图的。然后对每个顶点的所有邻接顶点进行排序,这样我们每次都优先选择字典序最小的那个顶点作为下次遍历的节点。我们做了后序遍历即可。最后还要把后序遍历的结果再翻转,才是从根节点出发到每个位置的路径。


最坏时间复杂度是O(VlogV),空间复杂度是O(E).
class Solution(object):
def findItinerary(self, tickets):
"""
:type tickets: List[List[str]]
:rtype: List[str]
"""
graph = collections.defaultdict(list)
for frm, to in tickets:
graph[frm].append(to)
for frm, tos in graph.items():
tos.sort(reverse=True)
res = []
self.dfs(graph, "JFK", res)
return res[::-1]
def dfs(self, graph, source, res):
while graph[source]:
v = graph[source].pop()
self.dfs(graph, v, res)
res.append(source)
相似题目
参考资料
https://www.youtube.com/watch?v=4udFSOWQpdg
日期
2018 年 10 月 30 日 —— 啊,十月过完了
【LeetCode】332. Reconstruct Itinerary 解题报告(Python)的更多相关文章
- [leetcode]332. Reconstruct Itinerary
Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], r ...
- 【LeetCode】120. Triangle 解题报告(Python)
[LeetCode]120. Triangle 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址htt ...
- LeetCode 1 Two Sum 解题报告
LeetCode 1 Two Sum 解题报告 偶然间听见leetcode这个平台,这里面题量也不是很多200多题,打算平时有空在研究生期间就刷完,跟跟多的练习算法的人进行交流思想,一定的ACM算法积 ...
- 【LeetCode】Permutations II 解题报告
[题目] Given a collection of numbers that might contain duplicates, return all possible unique permuta ...
- 【LeetCode】Island Perimeter 解题报告
[LeetCode]Island Perimeter 解题报告 [LeetCode] https://leetcode.com/problems/island-perimeter/ Total Acc ...
- 【LeetCode】01 Matrix 解题报告
[LeetCode]01 Matrix 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/01-matrix/#/descripti ...
- 【LeetCode】Largest Number 解题报告
[LeetCode]Largest Number 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/largest-number/# ...
- 【LeetCode】Gas Station 解题报告
[LeetCode]Gas Station 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/gas-station/#/descr ...
- LeetCode: Unique Paths II 解题报告
Unique Paths II Total Accepted: 31019 Total Submissions: 110866My Submissions Question Solution Fol ...
随机推荐
- 15.Pow(x, n)
Pow(x, n) Total Accepted: 88351 Total Submissions: 317095 Difficulty: Medium Implement pow(x, n). 思路 ...
- 11.13python第一周周末练习
2.请输出你的基本个人信息 3.结合逻辑判断,写一个不同学生分数,输出良好,优秀,分数不及格 循环输出 字符串的替换. 以什么开头startwith 以什么结尾endwith 列表转为字符串 字符串转 ...
- 【题解】洛谷P1001 A+B Problem
第一篇博客,献给2020年的残夏. 静听8月的热情与安宁,在竞赛中的时光如白驹过隙. 也不惧未知的风雨,努力向着既往的通途. 题目地址 https://www.luogu.com.cn/problem ...
- C++构造函数和析构函数初步认识
构造函数 1.构造函数与类名相同,是特殊的公有成员函数.2.构造函数无函数返回类型说明,实际上构造函数是有返回值的,其返回值类型即为构造函数所构建到的对象.3.当新对象被建立时,构造函数便被自动调用, ...
- echo -e "\033[字背景颜色;字体颜色m字符串\033[0m
格式: echo -e "\033[字背景颜色;字体颜色m字符串\033[0m" 例如: echo -e "\033[41;36m something here \033 ...
- Linux shell实现每天定时备份mysql数据库
每天定时备份mysql数据库任务,删除指定天数前的数据,保留指定天的数据: 需求: 1,每天4点备份mysql数据: 2,为节省空间,删除超过3个月的所有备份数据: 3,删除超过7天的备份数据,保留3 ...
- eclips 配置一个tomcat,启动多个不同端口的web项目
前提: 记录这个文章是因为在网上查资料,很多都是,用eclips.配置多个tomcat,就像下面图这样配置两个tomcat 去启动不同的web: 运动多个web 项目,设置不同的端口,需要多个tomc ...
- 【Java 8】函数式接口(二)—— 四大函数接口介绍
前言 Java8中函数接口有很多,大概有几十个吧,具体究竟是多少我也数不清,所以一开始看的时候感觉一脸懵逼,不过其实根本没那么复杂,毕竟不应该也没必要把一个东西设计的很复杂. 几个单词 在学习了解之前 ...
- Springboot 入门及Demo
一:SpringBoot入门1.1:SpringBoot简介Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的 ...
- shell脚本 系统状态信息查看
一.简介 源码地址 日期:2018/6/23 介绍:显示简单的系统信息 效果图: 二.使用 适用:centos6+,ubuntu12+ 语言:中文 注意:无 下载 wget https://raw.g ...