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:

  1. 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"].
  2. All airports are represented by three capital letters (IATA code).
  3. You may assume all tickets form at least one valid itinerary.

Example 1:
tickets = [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]]
Return ["JFK", "MUC", "LHR", "SFO", "SJC"].

Example 2:
tickets = [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]
Return ["JFK","ATL","JFK","SFO","ATL","SFO"].
Another possible reconstruction is ["JFK","SFO","ATL","JFK","ATL","SFO"]. But it is larger in lexical order.

Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.

这道题的意思是说有一些飞机票,要从这些票里面恢复出行程,每个行程都是从“JFK”开始的,如果有多种答案,就按照字典序取最小的那个。

乍一看好像挺简单的,每张票做个hash,然后跑一遍就行。

不过存在一个case,比如

[["JFK","KUL"],["JFK“,"NRT"],["NRT","JFK"]]

如果按照字典序,JFK有两个目的地,KUL和NRT。搜索时会先搜索KUL,这样就没后路了,应该要先搜索NRT。对于这个问题,

http://bookshadow.com/weblog/2016/02/05/leetcode-reconstruct-itinerary/的博主的第一种答案给出了方法。设定两个[], left 跟 right,搜索路径的时候如果没有回到出发地的让它靠后,让有出发地的靠前,这样可以保证看起来是合理的行程,其中为了防止在删路径的时候仍然访问删除的路径,还判断了下路径是否还存在着。

import collections
class Solution(object):
def findItinerary(self, tickets):
"""
:type tickets: List[List[str]]
:rtype: List[str]
"""
dest = collections.defaultdict(list)
for t in tickets:
dest[t[0]].append(t[1])
# for k, v in dest.iteritems():
# dest[k] = sorted(v) def dfs(start):
left, right = [], []
for end in sorted(dest[start]):
if end not in dest[start]:
continue
dest[start].remove(end)
subroute = dfs(end)
if start in subroute:
left += subroute
else:
right += subroute
return [start] + left + right return dfs("JFK")

其中 collections.defaultdict(list) 是内建了一个每次都能直接生成list的dict, 访问这个dict的时候如果没找到就直接生成一个list。

说回来这个问题应该是一个欧拉回路问题,即不重复的把图中所有边都走一遍。对于这个问题,有Hierholzer算法可以求解。

Hierholzer算法把每次访问的节点入栈,若节点无后续可访问的路径,则出栈,这样保持了每一个节点继续被访问的可能性。利用函数调用递归就是栈的特性,直接建立一个dfs函数,用它当栈,于是有:

class Solution(object):
def findItinerary(self, tickets):
"""
:type tickets: List[List[str]]
:rtype: List[str]
"""
dest = collections.defaultdict(list)
for t in tickets:
dest[t[0]].append(t[1])
for k,v in dest.iteritems():
dest[k]=sorted(v,reverse=True)
route=[]
def dfs(start):
while(dest[start]):
dfs(dest[start].pop())
route.append(start)
dfs("JFK")
return route[::-1]

最后返回这个出栈序列的反。

用c++实现如下:

#include<iostream>
#include<set>
#include<vector>
#include<unordered_map>
#include<algorithm>
#include<string>
using namespace std; class Solution {
public:
unordered_map<string,multiset<string>> dest;
vector<string> route;
void dfs(string start){
while(dest[start].size()>0){
auto pre= &dest[start];
string tmp = *(pre->begin());
pre->erase(pre->begin());
dfs(tmp);
}
route.push_back(start);
}
vector<string> findItinerary(vector<pair<string, string>> tickets){
for(auto e:tickets)
dest[e.first].insert(e.second);
dfs("JFK");
reverse(route.begin(),route.end());
return route;
}
};

其中利用multiset自带有序的特性,直接取出来。unordered_map比起map搜索时间更短,但耗费的空间更大。

总的来说,这道题还是挺有趣的,涉及到的一些知识点包括欧拉回路,Hierholzer算法,DFS等。

[leetcode]332. Reconstruct Itinerary的更多相关文章

  1. 【LeetCode】332. Reconstruct Itinerary 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 后序遍历 相似题目 参考资料 日期 题目地址:htt ...

  2. 【LeetCode】Reconstruct Itinerary(332)

    1. Description Given a list of airline tickets represented by pairs of departure and arrival airport ...

  3. 【LeetCode】332. Reconstruct Itinerary

    题目: Given a list of airline tickets represented by pairs of departure and arrival airports [from, to ...

  4. 332. Reconstruct Itinerary (leetcode)

    1. build the graph and then dfs -- graph <String, List<String>>,  (the value is sorted a ...

  5. 332 Reconstruct Itinerary 重建行程单

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

  6. 332. Reconstruct Itinerary

    class Solution { public: vector<string> path; unordered_map<string, multiset<string>& ...

  7. [LeetCode] Reconstruct Itinerary 重建行程单

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

  8. LeetCode Reconstruct Itinerary

    原题链接在这里:https://leetcode.com/problems/reconstruct-itinerary/ 题目: Given a list of airline tickets rep ...

  9. [Swift]LeetCode332. 重新安排行程 | Reconstruct Itinerary

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

随机推荐

  1. utils工具类

    使用工具类的方法 目录结构 o代表项目层 util.js 用promise避免异步获取不到数据的问题 注意module.exports var APIURL = ''; function getApi ...

  2. web前端调试的消除缓存对更改页面的影响

    平时调试网页的时候经常会短时间多次修改html和css文件,已达到最好的体验效果,但是有时候因为浏览器缓存的原因就导致虽然代码修改了,但是 页面还是没什么变化, 经常以为是自己代码修改的不对, 之后发 ...

  3. 第六节《Git克隆》

    本节学习如何使用git clone命令建立版本库克隆,以及如何使用git push和gitpull命令实现克隆之间的同步. Git的版本库目录和工作区在一起,因此存在一损俱损的问题,即如果删除一个项目 ...

  4. 注册Docker Hub、以及Push(九)

      一.注册   1.使用浏览器打开官网的时候,发现注册按钮点不了       2.下载google访问助手,添加到浏览器         下载地址:http://www.ggfwzs.com/,根据 ...

  5. 15.1 打开文件时的提示(不是dos格式)去掉头文件

    1.用ultraedit打开文件时,总提示不是DOS格式 2.把这个取消.dos格式只是用来在unix下读写内容的,此功能禁用即可.

  6. Spark编程指南分享

    转载自:https://www.2cto.com/kf/201604/497083.html 1.概述 在高层的角度上看,每一个Spark应用都有一个驱动程序(driver program).驱动程序 ...

  7. Linux基础入门-目录结构及文件基本操作

    一.Linux的目录结构: Windows是以存储介质为主的,主要以盘符及分区来实现文件的管理,然后之下才是目录.但Linux的磁盘从逻辑上来说是挂载在目录上的,每个目录不仅能使用本地磁盘分区的文件系 ...

  8. VMware 打开虚拟机的时候提示 internal error 内部错误 遇到这个问题时我的解决方法

    任务栏右键,启动任务管理器,选择“服务”选项卡 找到这个服务 启动这个服务后,再次尝试打开虚拟机,就OK了.

  9. storm中的一些概念

    1.topology 一个topolgy是spouts和bolts组成的图,通过stream groupings将图中的spout和bolts连接起来:如图所示: 一个topology会一直运行知道你 ...

  10. 为什么HTML中的多个空格或是回车在浏览器上只能显示出一个?

    我们在学习HTML的时候可能书本或是老师会告诉我们一件事,就是在HTML中不管我们在两个文本之间加上多少连续的空格或是回车,到了浏览器里面只能显示出一个来.但是我们从来不知道为什么. 原因很简单,因为 ...