Browse curriculum

Reconstruct Itinerary

Use every flight ticket exactly once, starting from JFK, and return the alphabetically smallest itinerary: an Eulerian path found with Hierholzer's algorithm.

Problem Understanding

Reconstruct Itinerary: given flight tickets [from, to], use every ticket exactly once to build a trip starting at "JFK". If several trips are possible, return the one that is smallest in alphabetical order.

Examples: [["MUC","LHR"],["JFK","MUC"],["SFO","SJC"],["LHR","SFO"]] returns ["JFK","MUC","LHR","SFO","SJC"]; [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]] returns ["JFK","ATL","JFK","SFO","ATL","SFO"].

The Intuition: Dead Ends Go Last

Using every ticket once means walking every directed edge once, an Eulerian path:

  1. Fly the smallest ticket first, because the answer must be alphabetically smallest.
  2. A stuck airport is not a failure. If the airport on top of the stack has no tickets left, every other ticket must be used before reaching it, so it belongs at the end of the trip. Pop it onto the route.
  3. Pop order is the trip backwards. Reverse the route at the end.

That is Hierholzer's algorithm, a depth-first search where nodes are recorded as they finish, the same post-order idea that Topological Sort uses. Course Schedule and Alien Dictionary are other directed-graph problems in the graphs pattern.

Interactive Walkthrough

GREEN ARROW = TICKET USED

SORT DESTINATIONS

stack

Empty

route (reversed)

Nothing popped yet

 

Group tickets by origin, destinations in alphabetical order: ATL → JFK, SFO; JFK → ATL, SFO; SFO → ATL

Next

Start the stack at JFK

Free preview: the first 5 of 14 steps

tickets

Airports are nodes and tickets are arrows; a used ticket turns green. The airport on top of the stack is solid, the rest of the stack is tinted, and airports already popped onto the route are green. Try Dead end to see the alphabetically first airport end up last.

Dry Run Table

Input: JFK→KUL, JFK→NRT, NRT→JFK. Sorted destinations: JFK: [KUL, NRT], NRT: [JFK].

Stack Top's tickets left Action Route (popped)
JFK KUL, NRT fly to KUL
JFK, KUL none pop KUL KUL
JFK NRT fly to NRT KUL
JFK, NRT JFK fly to JFK KUL
JFK, NRT, JFK none pop JFK KUL, JFK
JFK, NRT none pop NRT KUL, JFK, NRT
JFK none pop JFK KUL, JFK, NRT, JFK

Answer: reversed, JFK → NRT → JFK → KUL.

The Solution Template

Destinations kept sorted (a reverse-sorted list popped from the end, a priority queue, or a multiset), one stack, and a route reversed at the end.

Reconstruct Itinerary Code
1var findItinerary = function(tickets) {
2 const graph = new Map();
3 for (const [src, dst] of [...tickets].sort((a, b) => (a[0] + a[1] < b[0] + b[1] ? 1 : -1))) {
4 if (!graph.has(src)) graph.set(src, []);
5 graph.get(src).push(dst);
6 }
7 const route = [], stack = ['JFK'];
8 while (stack.length) {
9 const next = graph.get(stack[stack.length - 1]);
10 if (next && next.length) stack.push(next.pop());
11 else route.push(stack.pop());
12 }
13 return route.reverse();
14};

Edge Cases & Common Mistakes

  • Greedy without backing up: flying the smallest ticket and stopping at a dead end misses tickets; pop dead ends onto the route instead.
  • Duplicate tickets: the same route can appear twice; keep both (a list or multiset, not a set).
  • Forgetting to reverse: airports are popped in reverse trip order.
  • Sorting the wrong way for pop(): with a list popped from the end, sort destinations in reverse so the smallest comes off first.
  • Recursion depth: a recursive DFS goes one level per ticket; the iterative stack avoids deep recursion.

Summary

Sort each airport's destinations. From a stack starting at JFK, fly the smallest unused ticket while the top has one; otherwise pop the top onto the route. Reverse the route. O(E log E) time for sorting, O(E) space.

More practice: DSA interview questions with answers · patterns cheat sheet

The approach, step by step

  1. Sort destinations

    Group tickets by origin and keep each airport's destinations in alphabetical order.

  2. Walk with a stack

    Start with stack = [JFK]. While the top has tickets, fly the smallest one and push its destination; when it has none, pop it onto the route.

  3. Reverse

    When the stack is empty, the route reversed is the itinerary.

Frequently asked questions

Why doesn't a plain greedy walk work for Reconstruct Itinerary?

Always flying to the alphabetically smallest airport can strand you at a dead end while tickets are still unused. With JFK→KUL, JFK→NRT and NRT→JFK, greedy flies JFK→KUL first and gets stuck. The correct trip is JFK→NRT→JFK→KUL: the dead end has to come last.


How does Hierholzer's algorithm fix that?

It still flies the smallest ticket each time, but when an airport has no tickets left it pops that airport onto the route instead of failing. Dead ends are popped first, so they end up at the end of the reversed route, and the detours you took later get spliced in before them. Reversing the pop order gives a trip that uses every ticket.


Why is the result the lexically smallest itinerary?

At every airport the smallest available destination is tried first. Whenever the algorithm can continue the trip, it continues it in the smallest way, and it only defers a branch to the end of the trip when that branch is a dead end. That produces the smallest valid itinerary, which is what the problem asks for.


What is an Eulerian path?

A path in a graph that uses every edge exactly once. Each ticket is a directed edge, so a valid itinerary is an Eulerian path starting at JFK. The problem guarantees one exists; Hierholzer's algorithm finds it in time linear in the number of edges, plus the sorting.

New to the technique behind this problem? Watch it run step by step:

Topological Sort Visualization

Applying for software engineering roles? Free, no sign-up:

AI resume checker: match your resume to the job description