Reconstruct Itinerary — Hierholzer's Eulerian Path
Advertisement
Problem (LeetCode 332)
Given a list of airline tickets [from, to], reconstruct the itinerary in lexical order starting from "JFK". All tickets must be used exactly once.
This is an Eulerian path problem.
Hierholzer's Algorithm
DFS from start node:
While there are unvisited edges from u:
Pick smallest lexical neighbor v
Remove edge u→v
DFS(v)
Append u to result (post-order)
Result reversed = Eulerian path
Solutions
Python
from collections import defaultdict
import heapq
def findItinerary(tickets):
adj = defaultdict(list)
for src, dst in tickets:
heapq.heappush(adj[src], dst)
path = []
def dfs(u):
while adj[u]:
v = heapq.heappop(adj[u])
dfs(v)
path.append(u)
dfs("JFK")
return path[::-1]
JavaScript
function findItinerary(tickets) {
const adj={};
for(const[s,d]of tickets){if(!adj[s])adj[s]=[];adj[s].push(d);}
for(const k of Object.keys(adj))adj[k].sort().reverse();
const path=[];
const dfs=(u)=>{while(adj[u]&&adj[u].length)dfs(adj[u].pop());path.push(u);};
dfs("JFK"); return path.reverse();
}
Java
import java.util.*;
public List<String> findItinerary(List<List<String>> tickets) {
Map<String,PriorityQueue<String>> adj=new HashMap<>();
for(List<String>t:tickets)adj.computeIfAbsent(t.get(0),k->new PriorityQueue<>()).offer(t.get(1));
LinkedList<String>path=new LinkedList<>();
dfs("JFK",adj,path); return path;
}
void dfs(String u,Map<String,PriorityQueue<String>>adj,LinkedList<String>path){
PriorityQueue<String>q=adj.get(u);
while(q!=null&&!q.isEmpty())dfs(q.poll(),adj,path);
path.addFirst(u);
}
C++
#include <map>
#include <vector>
#include <string>
using namespace std;
map<string,multiset<string>> adj;
vector<string> path;
void dfs(string u){while(!adj[u].empty()){string v=*adj[u].begin();adj[u].erase(adj[u].begin());dfs(v);}path.push_back(u);}
vector<string> findItinerary(vector<vector<string>>&tickets){
for(auto&t:tickets)adj[t[0]].insert(t[1]);
dfs("JFK"); reverse(path.begin(),path.end()); return path;
}
C
/* C: adjacency list sorted alphabetically, DFS post-order, reverse result */
Key Insight
Post-order insertion means a node is added to result only after all its outgoing edges are exhausted — guaranteeing we never "get stuck" early.
Advertisement