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:
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.
Solution:DFS "一笔找Route"
思路: 类似拓扑排序Topological Sort DFS思路
区别在于是否可以有loop(这题可以有,所以不用check visisted)
Topological Sort DFS: http://www.jianshu.com/p/5880cf3be264
可参考210题 Course Schedule II solution2: http://www.jianshu.com/p/96841bf6f167
因为node是string,所以adj_list可以用map实现。
实现1_a: 结果存在linkedlist;
实现1_b: 结果存在stack;
其实目的是相同的。
Time Complexity: O(E) Space Complexity: O(E)
Solution1 Code:
class Solution {
Map> adj_map = new HashMap<>();
List route = new LinkedList<>();
public List findItinerary(String[][] tickets) {
route = new LinkedList<>();
adj_map = new HashMap<>();
for (String[] ticket : tickets)
adj_map.computeIfAbsent(ticket[0], k -> new PriorityQueue()).add(ticket[1]);
dfs("JFK");
return route;
}
private void dfs(String airport) {
while(adj_map.containsKey(airport) && !adj_map.get(airport).isEmpty()) {
String des = adj_map.get(airport).poll();
dfs(des);
}
route.add(0, airport);
}
}
Solution1b Code:
class Solution {
Map> adj_map = new HashMap<>();
Deque stack;
public List findItinerary(String[][] tickets) {
stack = new ArrayDeque<>();
adj_map = new HashMap<>();
for (String[] ticket : tickets)
adj_map.computeIfAbsent(ticket[0], k -> new PriorityQueue()).add(ticket[1]);
dfs("JFK");
return new ArrayList(stack);
}
private void dfs(String airport) {
while(adj_map.containsKey(airport) && !adj_map.get(airport).isEmpty()) {
String des = adj_map.get(airport).poll();
dfs(des);
}
stack.push(airport);
}
}
Round1
class Solution {
public List findItinerary(String[][] tickets) {
if(tickets == null || tickets.length == 0) return new ArrayList<>();
Map> adj_list = new HashMap<>();
Deque stack = new ArrayDeque<>();
// graph init
for(String[] ticket: tickets) {
if(!adj_list.containsKey(ticket[0])) {
adj_list.put(ticket[0], new PriorityQueue<>());
}
adj_list.get(ticket[0]).offer(ticket[1]);
}
dfs(adj_list, "JFK", stack);
return new ArrayList<>(stack);
}
private void dfs(Map> adj_list, String cur, Deque stack) {
if(adj_list.get(cur) != null) {
while(!adj_list.get(cur).isEmpty()) {
String next = adj_list.get(cur).poll();
dfs(adj_list, next, stack);
}
}
stack.push(cur);
}
}