Reconstruct Itinerary

hard graph dfs eulerian circuit

Problem

Given a list of airline tickets [from, to], return the itinerary that uses every ticket exactly once and starts at "JFK". If multiple valid itineraries exist, return the one with the smallest lexical order.

Inputtickets = [["MUC","LHR"],["JFK","MUC"],["SFO","SJC"],["LHR","SFO"]]
Output["JFK","MUC","LHR","SFO","SJC"]

def find_itinerary(tickets):
    from collections import defaultdict
    import heapq
    g = defaultdict(list)
    for a, b in tickets: heapq.heappush(g[a], b)
    route = []
    def dfs(u):
        while g[u]:
            dfs(heapq.heappop(g[u]))
        route.append(u)
    dfs("JFK")
    return route[::-1]
function findItinerary(tickets) {
  const g = {};
  for (const [a, b] of tickets) (g[a] = g[a] || []).push(b);
  for (const k in g) g[k].sort();
  const route = [];
  function dfs(u) {
    const list = g[u] || [];
    while (list.length) dfs(list.shift());
    route.push(u);
  }
  dfs("JFK");
  return route.reverse();
}
class Solution {
    Map<String, PriorityQueue<String>> g = new HashMap<>();
    LinkedList<String> route = new LinkedList<>();
    public List<String> findItinerary(List<List<String>> tickets) {
        for (var t : tickets) g.computeIfAbsent(t.get(0), k -> new PriorityQueue<>()).add(t.get(1));
        dfs("JFK");
        return route;
    }
    void dfs(String u) {
        PriorityQueue<String> pq = g.get(u);
        while (pq != null && !pq.isEmpty()) dfs(pq.poll());
        route.addFirst(u);
    }
}
unordered_map<string, multiset<string>> g;
vector<string> route;
void dfs(const string& u) {
    auto& s = g[u];
    while (!s.empty()) {
        string v = *s.begin();
        s.erase(s.begin());
        dfs(v);
    }
    route.push_back(u);
}
vector<string> findItinerary(vector<vector<string>>& tickets) {
    for (auto& t : tickets) g[t[0]].insert(t[1]);
    dfs("JFK");
    reverse(route.begin(), route.end());
    return route;
}
Time: O(E log E) Space: O(E)