[leetcode] 332. Reconstruct Itinerary 解题报告

题目链接: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:

  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:
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;
};










你可能感兴趣的:(LeetCode,图论,DFS)