作者: 负雪明烛
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)的更多相关文章

  1. [leetcode]332. Reconstruct Itinerary

    Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], r ...

  2. 【LeetCode】120. Triangle 解题报告(Python)

    [LeetCode]120. Triangle 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址htt ...

  3. LeetCode 1 Two Sum 解题报告

    LeetCode 1 Two Sum 解题报告 偶然间听见leetcode这个平台,这里面题量也不是很多200多题,打算平时有空在研究生期间就刷完,跟跟多的练习算法的人进行交流思想,一定的ACM算法积 ...

  4. 【LeetCode】Permutations II 解题报告

    [题目] Given a collection of numbers that might contain duplicates, return all possible unique permuta ...

  5. 【LeetCode】Island Perimeter 解题报告

    [LeetCode]Island Perimeter 解题报告 [LeetCode] https://leetcode.com/problems/island-perimeter/ Total Acc ...

  6. 【LeetCode】01 Matrix 解题报告

    [LeetCode]01 Matrix 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/01-matrix/#/descripti ...

  7. 【LeetCode】Largest Number 解题报告

    [LeetCode]Largest Number 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/largest-number/# ...

  8. 【LeetCode】Gas Station 解题报告

    [LeetCode]Gas Station 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/gas-station/#/descr ...

  9. LeetCode: Unique Paths II 解题报告

    Unique Paths II Total Accepted: 31019 Total Submissions: 110866My Submissions Question Solution  Fol ...

随机推荐

  1. 数据分析体系 — 用户粘性的两个计算指标(DAU/MAU和月人均活跃天数)

    很多运营都了解DAU(日活跃用户数)和MAU(月活跃用户数)的重要性,但在某些情况下这两个数值本身并不能反映出太多问题,这个时候就要引用到[DAU/MAU]的概念,即[日活/月活] 用户粘性的两个计算 ...

  2. CMSIS-RTOS 信号量Semaphores

    信号量Semaphores 和信号类似,信号量也是一种同步多个线程的方式,简单来讲,信号量就是装有一些令牌的容器.当一个线程在执行过程中,就可能遇到一个系统调用来获取信号量令牌,如果这个信号量包含多个 ...

  3. opencv学习(三)——绘图功能

    绘图功能 我们将学习以下函数:cv.line(),cv.circle(),cv.rectangle(),cv.ellipse(),cv.putText()等. 在这些功能中,有一些相同的参数: img ...

  4. mysql-centos8下安装

    参考文章 1.下载安装包 客服端与服务端 依赖包 2.linux下检查是否安装 rpm -qa | grep -i mysql 安装过会显示软件名称,没安装过就是空的 3.安装包传到虚拟机 先需要把安 ...

  5. Hadoop入门 完全分布式运行模式-准备

    目录 Hadoop运行环境 完全分布式运行模式(重点) scp secure copy 安全拷贝 1 hadoop102上的JDK文件推给103 2 hadoop103从102上拉取Hadoop文件 ...

  6. Flink(九)【Flink的重启策略】

    目录 1.Flink的重启策略 2.重启策略 2.1未开启checkpoint 2.2开启checkpoint 1)不设置重启策略 2)不重启 3)固定延迟重启(默认) 4)失败率重启 3.重启效果演 ...

  7. 商业爬虫学习笔记day4

    一.获取登录后页面信息的两种方法 1.第一种方法: 人为把有效cookies加到请求头中,代码如下 import urllib.request # 确定url url = "https:// ...

  8. 连接查询条件在on后面和条件在where后面

    emp表结构如下: dept表结构如下: 内连接 条件语句放在on 后面和 where 结果对于inner join结果是一样的 但对于left join 结果会产生不一样 这种现象也比较好理解,如果 ...

  9. Linux学习 - 输入输出重定向,管道符,通配符

    一.键盘输入读取read read [选项] [变量名] -p [显示信息] 在等待read输入时,输出提示信息 -t [秒数] 指定read输入等待时间 -n [字符数] 指定read只接收n个字符 ...

  10. ajaxSubmit返回JSON格式

    开发时遇到根据不同情况返回错误提示信息的需求,用到了ajax中返回json格式数据的. 前台请求代码: <script type="text/javascript">  ...