Cheapest Flights Within K Stops – Solution & Complexity

Solution Walkthrough

1. Bound the path length

  • At most k stops means at most k + 1 actual flight edges.
  • So you never need routes longer than k + 1 relaxations, even if the graph contains cycles.

2. Brute-force baseline

  • Explore all routes from src to dst with DFS while tracking how many stops remain.
  • That works for tiny graphs, but the branching factor makes it explode quickly.

3. Layered Bellman-Ford relaxation

  • Let prices[v] mean the cheapest known cost to reach city v using at most the previous number of edges.
  • On each of k + 1 rounds, copy the current array and relax every directed flight into the copy. Using the copy is crucial: it prevents one round from chaining together more than one new edge.
  • After k + 1 rounds, prices[dst] is the best cost using at most k + 1 edges, exactly matching the stop limit.

4. Final solution (all languages)

A copied distance array per round enforces the stop budget while keeping the implementation compact.

def find_cheapest_price(n: int, flights: list[list[int]], src: int, dst: int, k: int) -> int:
    prices = [float('inf')] * n
    prices[src] = 0

    for _ in range(k + 1):
        next_prices = prices[:]
        for start, end, price in flights:
            if prices[start] != float('inf') and prices[start] + price < next_prices[end]:
                next_prices[end] = prices[start] + price
        prices = next_prices

    return -1 if prices[dst] == float('inf') else prices[dst]

5. Why the copied array matters

  • If you relax into the same array you are reading from, one round might accidentally use two newly updated edges, violating the stop budget.
  • Using nextPrices guarantees round r only represents routes with at most r edges.
  • This is the same core Bellman-Ford idea, just stopped early because the interview problem limits the route length.

FAQ