Difficulty: Medium
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:
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.
Solution
思路
一开始我以为是简单的DFS算法,但发现Submission怎样都无法通过。后来才知道,原来题中“valid itinerary”是指,这个人所有的tickets必须连成一条完整的线,类似于一笔画,但首尾不一定要相连。
那该怎么完成这个一笔画呢。一个简单的解决办法是用后序遍历,再把遍历的这些地点倒序输出,即完成。
拿Discuss高票回答的例子来说,若输出[JFK, A, C, D, A, B, C, JFK, D]
则是错误的,因为这不能连成一笔画,这个人不可能从A凭空消失,出现在D并继续飞往B的。
正确的做法之一是,先后拓展了[JFK, A, C, D, A]
后,发现没路了,写出A
(push进vector<string> out
中,此时out
中的元素为[A]
),回到D
,再依次进入[B, C, JFK, D]
,没路了,写出D
,回到JFK
,发现也没路了,写出JFK
,如此类推。
最后out = [A, D, JFK, C, B, D, C, A, JFK]
。返回倒序的out
数组,完成。
代码
class Solution {
public:
vector<string> findItinerary(vector<pair<string, string>> tickets) {
for (auto t : tickets) {
route[t.first].insert(t.second);
}
dfs("JFK");
return vector<string>(output.rbegin(), output.rend());
}
private:
unordered_map<string, multiset<string>> route;
vector<string> output;
void dfs(string src) {
while (route[src].size()) {
auto p = route[src].begin();
string dst = *p;
route[src].erase(p);
dfs(dst);
}
output.push_back(src);
}
};