题目链接:https://leetcode.com/problems/reconstruct-itinerary/
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:
["JFK", "LGA"]
has a smaller lexical order than ["JFK", "LGB"]
.
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.
思路:最初的思路是top down的DFS,就是直接正向搜出正确路径,这样需要回朔状态,需要的时间复杂度很大.所以并不能过掉数据量大的数据.
看了别人的思路,基本是bottom up的DFS,就是路径是反向从最低层往上得出的.
将所有的机票用hash表保存起来,最后我们就是要找出一条路径将机票用完,并且如果有多条路径,就找字典序最小的.
我们可以构造一个hash表,key为一个地点字符串,value为一个multiset保存这个地点可以飞到的其他地方,之所以用multiset而不是set是因为从一个地方可以去别的地方几次.
并且这个数据结构是可以将数据排序的,方便我们有序的取数据.
然后我们利用DFS思想从"JFK"机场出发,按照字典序从小到达取与其连接的地点,从下一个地点再递归的搜索,直到没有和某地点相连的机票的了.我们就到达了最底层,然后往上返回路径即可.
栈和递归代码如下:
class Solution { public: vector<string> findItinerary(vector<pair<string, string>> tickets) { if(tickets.size()==0) return result; unordered_map<string, multiset<string>> hash; for(auto val: tickets) hash[val.first].insert(val.second); stack<string> st; st.push("JFK"); while(!st.empty()) { string s = st.top(); if(hash.find(s) !=hash.end() && hash[s].size()>0) { st.push(*hash[s].begin()); hash[s].erase(hash[s].begin()); } else { result.insert(result.begin(), s); st.pop();} } return result; } private: vector<string> result; };
第一种参考:https://leetcode.com/discuss/101723/very-short-iterative-java-solution
class Solution { public: void DFS(string str, unordered_map<string, multiset<string>>& hash) { while(hash.find(str)!=hash.end()&&hash[str].size()>0) { string tem = *hash[str].begin(); hash[str].erase(hash[str].begin()); DFS(tem, hash); } result.insert(result.begin(), str); } vector<string> findItinerary(vector<pair<string, string>> tickets) { if(tickets.size()==0) return result; unordered_map<string, multiset<string>> hash; for(auto val: tickets) hash[val.first].insert(val.second); DFS("JFK", hash); return result; } private: vector<string> result; };