332. Reconstruct Itinerary

Posted warmland

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了332. Reconstruct Itinerary相关的知识,希望对你有一定的参考价值。

ref: 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.


 

 

首先感觉就是普通的backtracking(dfs),但是写的时候疯狂在corner case报错

问题出在,

1. 比如jfk->sfo,还可以有jfk->atl,还可以有sfo->jfk,就是说可以有同一段旅程好几次倒腾,但是如果只是用普通的map的话,很难检测出重复的票。

2. 如果用tickets[][]里面的index表示的话,每次对tickets从头到尾找一遍太慢了,会tle

 

所以有一个答案写得很好: https://discuss.leetcode.com/topic/36721/short-c-dfs-iterative-44ms-solution-with-explanation-no-recursive-calls-no-backtracking/3

这个里面的点:

1. 我认为这道题的特别之处是,我知道这个不会有死路,就是这些机票确定是肯定是对的,只要沿着<from, to>走,就一定是对的,但是只是可能不是Lexical order上的最优,所以我认为不存在wrong path要回退

2. 用map<String, PriorityQueue<Stiring>>来实现同一个站greedy的走法,只要找到头了,就是对的

 

还有一点自己的, 就是看到有人留言说Stack这个已经被Java官方标记成的deprecated的类了,官方现在对于queue和stack建议统一使用Deque。

stack中的push() => offerFirst(). pop() => pollFirst(), peek()=> peekFirst()

queue中的 add() => offerLast(), remove() => pollFirst(), peek() => peekFirst()

我省略了add/remove一组,直接用offer/poll,第一组也存在,此处不写

 

 1     public List<String> findItinerary(String[][] tickets) {
 2         List<String> res = new ArrayList<String>();
 3         if(tickets.length == 0 || tickets[0].length == 0) {
 4             return res;
 5         }
 6         Map<String, PriorityQueue<String>> map = new HashMap<>();
 7         for(int i = 0; i < tickets.length; i++) {
 8             if(map.containsKey(tickets[i][0])) {
 9                 map.get(tickets[i][0]).add(tickets[i][1]);
10             } else {
11                 PriorityQueue<String> pq = new PriorityQueue<>();
12                 pq.offer(tickets[i][1]);
13                 map.put(tickets[i][0], pq);
14             }
15         }
16         Deque<String> stack = new ArrayDeque<>();
17         stack.offerFirst("JFK");
18         while(!stack.isEmpty()) {
19             String next = stack.peekFirst();
20             if(map.containsKey(next) && !map.get(next).isEmpty()) {
21                 stack.offerFirst(map.get(next).poll());
22             } else {
23                 res.add(stack.pollFirst());
24             }
25         }
26         Collections.reverse(res);
27         return res;
28     }

 

以上是关于332. Reconstruct Itinerary的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode 332: Reconstruct Itinerary

[LeetCode] 332. Reconstruct Itinerary

332. Reconstruct Itinerary

[LeetCode] 332. Reconstruct Itinerary Java

332. Reconstruct Itinerary --- DFS转迭代,用栈

Leetcode 332 重新安排行程(欧拉路径)