题目【难度:Medium】:
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.
给定一系列机票,用起点和终点地[from,to]组成的字符串表示,根据这些机票重构完整的航程,已知所有航程由JFK开始。
有多个解时,取最小字典序的解。
解题思路
根据题目,很自然地会画出一幅图,所以可以想到用图的搜索算法找出完整航程,BFS肯定不行,考虑DFS,题目说给定的机票一定有解,所以这个图有特点,就是除了起点和终点,中间节点的入度总等于出度,如果DFS访问到最后那么一定就到了航程的终点,这样看,这题可以用DFS求解。
在编写程序的时候,要注意本题的DFS其实需要一些变化,访问过的点也可能再次被访问,事实上有多少条边就需要有多少个输出,而不是有多少个节点就有多少个输出。题目给定了DFS的起点,因此可以认为每个起点都可以对应多个终点,这些终点可以重复(使用multiset实现),构建图的时候每加一条边就为对应的起点加了一个终点,在DFS时注意入栈前把已访问的节点删除。DFS在终点先返回,所以最后要讲结果倒转。
代码
#include <iostream>
#include <vector>
#include <unordered_map>
#include <set>
#include <algorithm>
#include <utility>
using namespace std;
class Solution {
unordered_map<string, multiset<string> > graph;
vector<string> itinerary;
void dfs(const string& airport) {
string next_airport;
while (graph[airport].size() != 0) {
next_airport = *graph[airport].begin();
graph[airport].erase(graph[airport].begin());
dfs(next_airport);
}
itinerary.push_back(airport);
}
public:
vector<string> findItinerary(vector<pair<string, string> > tickets) {
graph.clear();
itinerary.clear();
for (unsigned int i = 0; i < tickets.size(); ++i)
graph[tickets[i].first].insert(tickets[i].second);
string begin_airport("JFK");
dfs(begin_airport);
reverse(itinerary.begin(), itinerary.end());
return itinerary;
}
};
int main() {
Solution s;
vector<pair<string, string> > tickets;
vector<string> itinerary;
tickets.push_back(make_pair("JFK", "SFO"));
tickets.push_back(make_pair("JFK", "ATL"));
tickets.push_back(make_pair("SFO", "ATL"));
tickets.push_back(make_pair("ATL", "JFK"));
tickets.push_back(make_pair("ATL", "SFO"));
itinerary = s.findItinerary(tickets);
for (unsigned i = 0; i < itinerary.size(); ++i)
cout << itinerary[i] << " ";
cout << endl;
tickets.clear();
tickets.push_back(make_pair("JFK", "AAA"));
tickets.push_back(make_pair("AAA", "JFK"));
tickets.push_back(make_pair("JFK", "BBB"));
tickets.push_back(make_pair("JFK", "CCC"));
tickets.push_back(make_pair("CCC", "JFK"));
itinerary = s.findItinerary(tickets);
for (unsigned i = 0; i < itinerary.size(); ++i)
cout << itinerary[i] << " ";
cout << endl;
tickets.clear();
tickets.push_back(make_pair("MUC", "LHR"));
tickets.push_back(make_pair("JFK", "MUC"));
tickets.push_back(make_pair("SFO", "SJC"));
tickets.push_back(make_pair("LHR", "SFO"));
itinerary = s.findItinerary(tickets);
for (unsigned i = 0; i < itinerary.size(); ++i)
cout << itinerary[i] << " ";
cout << endl;
tickets.clear();
return 0;
}