Leetcode: 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:
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 may 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.

refer to Recursion https://leetcode.com/discuss/84702/share-my-solution

and Iteration https://leetcode.com/discuss/84706/share-solution-java-greedy-stack-15ms-with-explanation

Explanation https://leetcode.com/discuss/84659/short-ruby-python-java-c

enter image description here

這一道題不能用Topological sort是因為topological sort只能在DAG(A指Acyclic)里面找出一條路徑,而這里只是directed graph, 環是可能存在的

 

Eulerian Path

This problem is to find Eulerian path. Greedy DFS, building the route backwards when retreating.

所以應該找Eulerian Path(visit each edge exactly once), 因為題目說了all tickets form at least one valid itinerary. 所以Eulerian Path一定是存在的

所以,start from JFK, 我們用Hierholzer's algorithm來找Eulerian Path

Eulerian Path可能不是唯一的, 比如上圖有兩條:JFK-D-A-C-D-B-C-JFK-A 以及 JFK-A-C-D-B-C-JFK-D-A

因為題目限制了lexical order,所以找出來應該是第二條,用一個heap來實現有多個鄰居選擇的時候優先選擇哪一個

下面是重點:greedy的Hierholzer's algorithm

First keep going forward until you get stuck. Put the stuck element always at the front of the result list(stuck element將會在我們最后的eulerian path的尾部,也就是最后走到這里去,因為先走到這里去會stuck). Try if it is possible to travel to other places from the airport on the way.

From JFK we first visit JFK -> A -> C -> D -> A. There we're stuck, so we write down A as the end of the route and retreat back to D. There we see the unused ticket to B and follow it: D -> B -> C -> JFK -> D. Then we're stuck again (because D->A has been polled), retreat and write down the airports while doing so: Write down D before A, then JFK before D, the c before JFK, etc. When we're back from our cycle at D, the written route is D -> B -> C -> JFK -> D -> A. Then we retreat further along the original path, prepending C, A and finally JFK to the route, ending up with the route JFK -> A -> C -> D -> B -> C -> JFK -> D -> A.

Since the problem asks for lexical order smallest solution, we can put the neighbors in a min-heap. In this way, we always visit the smallest possible neighbor first in our trip.

Use LinkedList as the result type because we always add at the front of the list

 1 public class Solution {
 2     LinkedList<String> res;
 3     Map<String, PriorityQueue<String>> mp;
 4     
 5     public List<String> findItinerary(String[][] tickets) {
 6         if (tickets==null || tickets.length==0) return new LinkedList<String>();
 7         res = new LinkedList<String>();
 8         mp = new HashMap<String, PriorityQueue<String>>();
 9         for (String[] ticket : tickets) {
10             if (!mp.containsKey(ticket[0])) {
11                 mp.put(ticket[0], new PriorityQueue<String>());
12             }
13             mp.get(ticket[0]).offer(ticket[1]);
14         }
15         dfs("JFK");
16         return res;
17     }
18     
19     public void dfs(String cur) {
20         while (mp.containsKey(cur) && !mp.get(cur).isEmpty()) {
21             dfs(mp.get(cur).poll());
22         }
23         res.addFirst(cur);
24     }
25 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM