AlgoMaster Logo

Reconstruct Itinerary

hardFrequency5 min readUpdated June 23, 2026

Understanding the Problem

This problem is about finding an Eulerian path in a directed graph. Each ticket is a directed edge from one airport to another, and we need to traverse every edge exactly once, starting from "JFK." When multiple valid paths exist, we return the one that is smallest when read as a single string.

This is not a standard DFS over nodes. We need to traverse every edge exactly once, which means we may visit the same airport multiple times. In Example 2, JFK, ATL, and SFO are each visited twice. Traversing every edge exactly once is the defining condition of an Eulerian path, and Hierholzer's algorithm is the standard method for constructing one.

Key Constraints:

  • 1 <= tickets.length <= 300 → With at most 300 edges, an O(E log E) traversal is well within limits, and a backtracking solution that explores a few dead ends still runs fast.
  • from_i.length == 3, to_i.length == 3 → Airport codes are always 3 uppercase letters, so string comparisons take constant time.
  • "All tickets form at least one valid itinerary" → An Eulerian path is guaranteed to exist, so the algorithm needs no existence check.
  • "Must use all tickets exactly once" → Identical routes can appear more than once, so we track the count of remaining tickets per route rather than a single boolean per edge.

Approach 1: DFS with Backtracking

Intuition

Build a graph from the tickets, sort each airport's destinations lexicographically, then do a DFS from "JFK," trying to use all tickets. If a branch reaches a dead end before all tickets are used, backtrack and try the next destination at the most recent choice point.

Sorting the destinations means that at every airport we attempt the lexicographically smallest option first. The first complete path we find (one that uses all tickets) is therefore the smallest valid itinerary, so we can return as soon as we find it.

Algorithm

  1. Build an adjacency list from the tickets. For each departure airport, store a sorted list of destination airports.
  2. Track which tickets have been used (since the same route can appear multiple times, we track ticket usage, not just edge existence).
  3. Start DFS from "JFK." At each airport, try destinations in sorted order.
  4. For each destination, mark the ticket as used and recurse. If the recursion uses all tickets, we've found our answer.
  5. If not, unmark the ticket (backtrack) and try the next destination.

Example Walkthrough

1Start at JFK. Sorted neighbors: JFK->[ATL,SFO], ATL->[JFK,SFO], SFO->[ATL]
0
JFK
1/6

Code

Backtracking can revisit many partial paths before finding the answer. The next approach builds the itinerary in a single traversal, with no undoing.

Approach 2: Hierholzer's Algorithm (Optimal)

Intuition

Hierholzer's algorithm constructs an Eulerian path without backtracking. Do a DFS, always visiting the lexicographically smallest unused neighbor. When an airport has no more outgoing tickets, add it to the front of the result and return to its caller.

Building the path in reverse works because of what a dead end represents. When the DFS gets stuck at an airport with no remaining tickets, every edge out of that airport has already been consumed, so that airport must come last among all the nodes still on the current call stack. Adding dead ends to the front places the tail of the path first, and the rest of the path fills in ahead of it as each recursive call returns.

Algorithm

  1. Build an adjacency list where each airport maps to a min-heap (priority queue) of its destinations.
  2. Start DFS from "JFK."
  3. At each airport, while there are unused outgoing tickets, pop the smallest destination and recurse.
  4. When no more outgoing tickets remain (dead end), add the current airport to the front of the result.
  5. The final result is the Eulerian path in the correct order.

Example Walkthrough

1DFS from JFK. Heap: JFK->[ATL,SFO], ATL->[JFK,SFO], SFO->[ATL]. Result: []
1/7

Code