1. 程式人生 > >LeetCode332 - Reconstruct Itinerary(重新安排行程 圖轉樹 後序遍歷)

LeetCode332 - Reconstruct Itinerary(重新安排行程 圖轉樹 後序遍歷)

LeetCode332 - Reconstruct Itinerary(重新安排行程 圖轉樹 後序遍歷)

題目連結

題目

在這裡插入圖片描述

解析

  • 由於必須要按照字典序最小的來訪問某個結點的孩子,所以在查詢節點的孩子的map中使用一個優先佇列存放,每次取出來的是字典序最小的;

  • 然後按照類似後序遍歷的順序遍歷這個圖(先訪問自己孩子,然後訪問自己),然後在反轉過來,這樣可以得到正確的答案;

  • 也可以理解為dfs的時候,是先訪問自己的孩子,然後訪問自己,最後將訪問的順序翻轉過來即可,需要注意的時候一定要使用後序的方式,不然會在選擇的時候出錯(或者說不能正確訪問所有的結點);

在這裡插入圖片描述

class Solution {
    
    private HashMap<String, PriorityQueue<String>> map;
    private List<String>res;
    
    public List<String> findItinerary(String[][] tickets) {
        res = new LinkedList<>();
        map = new HashMap<>();
        for (String[
] s : tickets) { if (map.get(s[0]) == null) { PriorityQueue<String>pq = new PriorityQueue<>(); pq.add(s[1]); map.put(s[0], pq); }else { map.get(s[0]).add(s[1]); } } visit("JFK"
); return res; } public void visit(String cur) { while(map.containsKey(cur) && !map.get(cur).isEmpty()) visit(map.get(cur).poll()); // 訪問孩子(最小的孩子)並刪除這條邊 res.add(0, cur); // 在頭部新增 (雙向佇列) } }

非遞迴寫法:

class Solution {
    
    private HashMap<String, PriorityQueue<String>> map;
    private List<String>res;
    
    public List<String> findItinerary(String[][] tickets) {
        res = new LinkedList<>();
        map = new HashMap<>();
        for (String[] s : tickets) {
            if (map.get(s[0]) == null) {
                PriorityQueue<String>pq = new PriorityQueue<>();
                pq.add(s[1]);
                map.put(s[0], pq);
            }else {
                map.get(s[0]).add(s[1]);
            }
        }
        Stack<String>stack = new Stack<>();
        stack.push("JFK");
        while(!stack.isEmpty()){
            while(map.containsKey(stack.peek()) && !map.get(stack.peek()).isEmpty())
                stack.push(map.get(stack.peek()).poll());
            res.add(0, stack.pop());
        }
        return res;
    }
}

C++:

class Solution {
public:
    vector<string> findItinerary(vector<pair<string, string>> tickets) {
        for(const auto & pair : tickets)
            map[pair.first].insert(pair.second);
        visit("JFK");
        return vector<string>(res.rbegin(), res.rend());
    }
private:
    unordered_map<string, multiset<string>>map;
    vector<string>res;
    
    void visit(string cur){
        while(map[cur].size()){
            string next = *map[cur].begin();
            map[cur].erase(map[cur].begin());
            visit(next);
        }
        res.push_back(cur);
    }
};