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.
Tips:
题意:给定一些飞机票,让你从中找出一个序列可以全部用完。要求如下:
1.从JFK出发。
2.如果有多个解,输出字典序最小的。
思路:
一直DFS直到arrival的pq取完,然后加最后一个城市,addFirst。
All the airports are vertices and tickets are directed edges. Then all these tickets form a directed graph.
The graph must be Eulerian since we know that a Eulerian path exists.
Thus, start from "JFK", we can apply the Hierholzer's algorithm to find a Eulerian path in the graph which is a valid reconstruction.
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.
Code:
Recursive:
public class Solution {
public List<String> findItinerary(String[][] tickets) {
LinkedList<String> result = new LinkedList<>();
if (tickets == null || tickets.length == 0) {
return result;
}
HashMap<String, PriorityQueue<String>> map = new HashMap<>();
for (String[] ticket : tickets) {
/*if (!map.containsKey(ticket[0])) {
map.put(ticket[0], new PriorityQueue<String>());
}*/
map.putIfAbsent(ticket[0], new PriorityQueue<>());
map.get(ticket[0]).add(ticket[1]);
}
dfs(result, map, "JFK");
return result;
}
private void dfs(LinkedList<String> result, HashMap<String, PriorityQueue<String>> map, String current) {
while (map.containsKey(current) && !map.get(current).isEmpty()) {
dfs(result, map, map.get(current).poll());
}
result.addFirst(current);
}
}
Stack:
public List<String> findItinerary(String[][] tickets) {
Map<String, PriorityQueue<String>> targets = new HashMap<>();
for (String[] ticket : tickets)
targets.computeIfAbsent(ticket[0], k -> new PriorityQueue()).add(ticket[1]);
List<String> route = new LinkedList();
Stack<String> stack = new Stack<>();
stack.push("JFK");
while (!stack.empty()) {
while (targets.containsKey(stack.peek()) && !targets.get(stack.peek()).isEmpty())
stack.push(targets.get(stack.peek()).poll());
route.add(0, stack.pop());
}
return route;
}