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.
Analysis:
Use DFS. Termination: when all tickets are used. Invalid: if haven't used all ticket, but reach some city without any outgoing tickets.
Solution:
1 public class Solution { 2 public class TicketGroup { 3 List<String> outList; 4 boolean[] visited; 5 6 public TicketGroup(String firstOutCity){ 7 outList = new ArrayList<String>(); 8 outList.add(firstOutCity); 9 } 10 } 11 12 public List<String> findItinerary(String[][] tickets) { 13 List<String> resList = new ArrayList<String>(); 14 if (tickets.length == 0) return resList; 15 16 HashMap<String,TicketGroup> graph = new HashMap<String,TicketGroup>(); 17 for (String[] ticket : tickets){ 18 if (graph.containsKey(ticket[0])){ 19 graph.get(ticket[0]).outList.add(ticket[1]); 20 } else { 21 TicketGroup group = new TicketGroup(ticket[1]); 22 graph.put(ticket[0],group); 23 } 24 } 25 for (TicketGroup group : graph.values()){ 26 Collections.sort(group.outList); 27 group.visited = new boolean[group.outList.size()]; 28 } 29 30 resList.add("JFK"); 31 findItineraryRecur("JFK",graph,resList,tickets.length+1); 32 return resList; 33 } 34 35 public boolean findItineraryRecur(String cur, HashMap<String,TicketGroup> graph, List<String> resList, int maxLen){ 36 if (resList.size() == maxLen) 37 return true; 38 39 if (!graph.containsKey(cur)) return false; 40 boolean available = false; 41 TicketGroup curGroup = graph.get(cur); 42 for (boolean visit : curGroup.visited) 43 if (!visit){ 44 available = true; 45 break; 46 } 47 if (!available) return false; 48 49 for (int i=0;i<curGroup.visited.length;i++){ 50 if (!curGroup.visited[i]){ 51 curGroup.visited[i] = true; 52 resList.add(curGroup.outList.get(i)); 53 if (findItineraryRecur(curGroup.outList.get(i),graph,resList,maxLen)){ 54 return true; 55 } 56 resList.remove(resList.size()-1); 57 curGroup.visited[i] = false; 58 } 59 } 60 return false; 61 } 62 }