332. Reconstruct Itinerary

332. Reconstruct Itinerary

  • 方法1:
    • 易错点:
  • 方法2:

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.

思路:

这道题是有向图的搜索问题,需要快速查找从一个机场能到达的终点,所以考虑用hash来建立对应,c++中的unordered_map。而每一个机场对应的终点1. 可以有很多,2. 可以重复,3. 优先考虑lexical order在前的机场,因此最适合的结构是multiset。建立hash之后就可以用dfs进行线路的搜索。

知识点:topological sort 和dfs有何不同?
https://www.geeksforgeeks.org/topological-sorting/

需要的数据结构有:
unordered_map>

方法1:

思路:
这种解法用dfs,每次选则终点中排序第一的,删掉这张票,递归搜索。仅当始发地没有目的地时可以打印出始发地,并且依次放回,如果上一个始发地还有票,继续dfs,如果没有,打印,继续返回。

所以这种打印的方式相当于postorder traversal。

易错点:

  1. 这里helper function里unordered_map> & m中的 reference就异常重要了:因为在每一层递归中, 我们都会对这个hash进行修改,不断删除已经用过的ticket,必须使用reference。
class Solution {
public:
    vector<string> findItinerary(vector<pair<string, string>> tickets) {
        vector<string> result;
        unordered_map<string, multiset<string>> m;
        for (auto ticket: tickets){
            m[ticket.first].insert(ticket.second);
        }
        
        dfs(m, "JFK", result);
        return vector<string> (result.rbegin(), result.rend());
    }
    
    void dfs(unordered_map<string, multiset<string>> & m, string start, vector<string> & result){
        while (m[start].size() != 0){
                string end = *m[start].begin();
                m[start].erase(m[start].find(end));
                dfs(m, end, result);
            }
        
        result.push_back(start);         
        return;      
    } 
};

方法2:

grandyang: http://www.cnblogs.com/grandyang/p/5183210.html
因为相当于图的postorder traversal,也可以用stack来实现。我们将一个vertex入栈,当且仅当它没有它能到达的子节点。

你可能感兴趣的:(leetcode,dfs,stack)