LeetCode 332. Reconstruct Itinerary

Problem:

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.

Solution:

DFS+backtracking. At first I did not realize all tickets have to be used. Reading the question thoroughly is very important.

public class Solution {
    Map<String, List<String>> g = new HashMap<String, List<String>>();
    List<String> sol = new ArrayList<String>();
    int size;
    
    public List<String> findItinerary(String[][] tickets) {
        for (int i = 0; i < tickets.length; i++) {
            String from = tickets[i][0];
            String to = tickets[i][1];
            if (!g.containsKey(from)) {
                List<String> opts = new ArrayList<String>();
                opts.add(to);
                g.put(from, opts);
            }
            else {
                List<String> opts = g.get(from);
                opts.add(to);
                g.put(from, opts);
            }
        }
        
        sol.add("JFK");
        size = tickets.length + 1;
        find(sol);
        return sol;
    }
    
    private boolean find(List<String> current) {
        if (current.size() == size) return true;
        String start = current.get(current.size() - 1);
        List<String> opts = g.get(start);
        if (opts == null || opts.size() == 0) {
            return false;
        }
        Collections.sort(opts);
        for (int i = 0; i < opts.size(); i++) {
            String opt = opts.get(i);
            current.add(opt);
            opts.remove(i);
            if (find(current)) return true;
            opts.add(i, opt);
            current.remove(current.size() - 1);
        }
        return false;
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *