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

public class Solution {
    public List<String> findItinerary(String[][] tickets) {
        List<String> ans = new ArrayList<String>();
        if(tickets == null || tickets.length == 0) return ans;

        Map<Integer, List<Integer> > map = new HashMap<Integer, List<Integer>>();
        for(int i = 0; i < tickets.length; i++) {
            int from = hash(tickets[i][0]);
            int to   = hash(tickets[i][1]);
            if(!map.containsKey(from)) map.put(from, new ArrayList<Integer>());
            map.get(from).add(to);
        }

        for(Integer start: map.keySet()) Collections.sort(map.get(start));

        Stack<Integer> path = new Stack<Integer>();
        path.add(hash("JFK"));
        while(path.size() != 0) {
            int cur = path.peek();
            List<Integer> dst = map.get(cur);
            if( dst == null || dst.size() == 0) {
                ans.add(decode(path.pop()));    
            } else {
                path.push(dst.remove(0));
            }        
        }

        List<String> realAns = new ArrayList<String>();
        for(int i = 0; i < ans.size(); i++) realAns.add(ans.get(ans.size() - i - 1));
        return realAns;
    }


    public int hash(String city) {
        return ( (int)city.charAt(0) << 16) | ( (int)city.charAt(1) << 8) | ( (int)city.charAt(2));
    }

    public String decode(int c) {
        return ""+
        (char) ((c >> 16)&0xFF) + 
        (char) ((c >> 8)&0xFF) + 
        (char) ((c)&0xFF);
    }
}

results matching ""

    No results matching ""