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. html基础学习笔记1

    <!DOCTYPE html> 声明为 HTML5 文档  <html> 元素是 HTML 页面的根元素 <head> 元素包含了文档的元(meta)数据,如 &l ...

  2. nc--windows下工具分享

    1.在windows下安装了9个memcached. 一些测试需要经常对这9个memcached的执行flush_all的操作 由于windows没有linux那样可以使用nc命令. 经过不懈搜索,找 ...

  3. 剑指offer 12.代码的完整性 数值的整数次方

    题目描述 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方.   本人渣渣代码: public double Power(double ba ...

  4. request&response

    /* request&response 1.什么是HttpServletRequest HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP ...

  5. Mysql中判断一个点是否落在多边形内

    关于地理空间数据,经常需要处理两个空间数据的关联关系.有很多种方法可以处理,通过编写程序算法,或者是调用数据库中对应的function.在mysql数据库中,https://dev.mysql.com ...

  6. 工控随笔_04_西门子_解决Step 7软件因授权问题不能打开的方式和方法

    西门子的软件是授权软件,只有经过授权认证的用户才能使用,如果没有通过授权认证则不能 正常的使用软件的相关功能. 一.西门子授权不成功问题 如上图所示报故障代码: 000001-0505.报警文本为:未 ...

  7. vim汇总

    跳到100行 100gg :100    

  8. idea导入svn项目

    起初和导入git项目一样,file - new - project from version control - ,这后面选 subversion. 在打开的 checkout from subver ...

  9. 51nod1986 Jason曾不想做的数论题

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1986 方便起见,公式中的区间内只考虑整数,X的gcd,lcm定义为每个元 ...

  10. Ubuntn16.04.3安装Hadoop3.0+scale2.12+spark2.2

    Ubuntn16.04.3安装Hadoop3.0+scale2.12+spark2.2 对比参照此博文.bovenson 前言:因为安装的Hadoop.Scale是基于JAVA的应用程序,所以必须先安 ...