【LeetCode】332. Reconstruct Itinerary

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/KID_LWC/article/details/82588917

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:

  1. 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"].
  2. All airports are represented by three capital letters (IATA code).
  3. 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;
        }
    };

猜你喜欢

转载自blog.csdn.net/KID_LWC/article/details/82588917