1. 题目描述
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.
2. 思路
- 将航线抽象建模为一个图,则题目的意思为 找出一条航线其可以由所有的票连接而成,若有多条,则选取字典序最小的那条航线。
- 航线的起点为”JFK”节点,当一个节点的出度为0时,其必定为航线的终点。
- 由于邻接边用multiset表示,当前的票已经排序,所以深度遍历时,只要存在边被遍历完,则必然是字典序最小的那条。
3. 代码及复杂度分析
class Solution {
public:
vector<string> findItinerary(vector<pair<string, string>> tickets) {
map<string, multiset<string>> targets;
for (auto ticket : tickets)
targets[ticket.first].insert(ticket.second);
vector<string> itenary;
stack<string> s;
s.push("JFK");
while (!s.empty()) {
string curr_airport = s.top();
if (targets[curr_airport].empty()) {
itenary.push_back(curr_airport);
s.pop();
} else {
s.push(*(targets[curr_airport].begin()));
targets[curr_airport].erase(targets[curr_airport].begin());
}
}
reverse(itenary.begin(), itenary.end());
return itenary;
}
};