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:
Input:
[["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]]
Output:["JFK", "MUC", "LHR", "SFO", "SJC"]
Example 2:
Input:
[["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]
Output:["JFK","ATL","JFK","SFO","ATL","SFO"]
Explanation: Another possible reconstruction is["JFK","SFO","ATL","JFK","ATL","SFO"]
. But it is larger in lexical order.
题解:本题就是通过dfs找出一条遍历所有边的路径,因为本题保证了路径必定存在,所以在访问时按照字典序顺序递归出口只有一个,也就是无论如何dfs必定能使得返回的递归栈存储的节点是所求路径(因为最先递归出来的必定是没有回路没有出度的节点),我自己用的方法没有注意到这点用深度来维护递归层数,比较多余,还有犯的错误有:没有引用,子dfs中没有更新节点,没有用优先队列优化代码,因为不是用优先队列(dfs时没有弹出已经访问的边)所以已经访问的边需要用map维护,这里已经访问的边可能有多条就是a点到b点有多条同向的边所以需要map维护时记录该边对应的次数,直接用优先队列则可以直接弹出访问的点,多条边也因为优先队列存储了多个同样节点得到解决,访问路径只需在递归结束后push到一个路径数组即可。
class Solution {
public:
vector<string> findItinerary(vector<pair<string, string>> tickets) {
int depth=0;
map<string,vector<string>> G;
int len=tickets.size();
map<pair<string,string>,int> vis;
for(auto x:tickets){
G[x.first].push_back(x.second);
if(vis.find(make_pair(x.first,x.second))==vis.end()) vis[make_pair(x.first,x.second)]=1;
else vis[make_pair(x.first,x.second)]++;
}
map<string,vector<string>>::iterator iter;
for(iter = G.begin(); iter != G.end(); iter++){
sort((iter->second).begin(),(iter->second).end());
}
stack<string> q;
dfs(G,"JFK",depth,len,vis,q);
vector<string> ans(len+1,"");
int k=len;
while(!q.empty()){
string x=q.top();
q.pop();
ans[k--]=x;
}
return ans;
}
void dfs(map<string,vector<string>> G,string u,int& depth,int len,map<pair<string,string>,int>& vis,stack<string>& q){
q.push(u);
if(depth==len) return;
depth++;
for(auto x:G[u]){
if(vis[make_pair(u,x)]!=0){
vis[make_pair(u,x)]--;
dfs(G,x,depth,len,vis,q);
}
}
if(depth<len){
string s1=q.top();
q.pop();
string s2=q.top();
vis[make_pair(s2,s1)]++;
depth--;
return;
}
}
};
别人的解法:
class Solution {
unordered_map<string, priority_queue<string, vector<string>, greater<string>>> graph;
vector<string> result;
void dfs(string vtex)
{
auto & edges = graph[vtex];
while (!edges.empty())
{
string to_vtex = edges.top();
edges.pop();
dfs(to_vtex);
}
result.push_back(vtex);
}
public:
vector<string> findItinerary(vector<pair<string, string>> tickets) {
for (auto e : tickets)
graph[e.first].push(e.second);
dfs("JFK");
reverse(result.begin(), result.end());
return result;
}
};