Talentd
FleetCode
Make and follow sheets.Sign in

Cheapest Flights Within K Stops solution and explanation

MediumBreadth-First SearchDepth-First SearchDynamic ProgrammingGraph6 min read42.7% acceptanceUpdated 9 Apr 2026
G-38. Cheapest Flights Within K Stopstake U forward · 23:56 · 345K viewsWatch on YouTube
9 more videos on this problem
  1. G-38. Cheapest Flights Within K Stopstake U forward · 23:56 · 345K views
  2. Bellman-Ford - Cheapest Flights within K Stops - Leetcode 787 - PythonNeetCode · 20:24 · 156K views
  3. Cheapest Flights Within K Stops | DFS + Pruning | Leetcode #787Techdose · 18:29 · 45K views
  4. Cheapest Flights Within K Stops | GOOGLE | BFS | Explanation ➕ Live CodingcodestorywithMIK · 31:54 · 24K views
  5. LeetCode 787. Cheapest Flights Within K Stops | Dijkstra Solution Explained [2022]Shiran Afergan · 8:59 · 15K views
  6. Cheapest Flights Within K Stops | Graph ProblemShradha Khapra · 30:29 · 7K views
  7. 787. Cheapest Flights Within K Stops | Dijkstras | BFS | Complete Internal WorkingAryan Mittal · 35:16 · 6K views
  8. LeetCode 787. Cheapest Flights Within K Stops Explanation and Solutionhappygirlzt · 9:41 · 6K views
  9. Cheapest Flights Within K Stops - Leetcode 787 Python | Algorithm explained | Dijkstra AlgorithmPersistent Programmer · 25:27 · 3K views
  10. Leetcode - Cheapest Flights Within K Stops (Python)Timothy H Chang · 8:41 · 2K views

The problem

There are n cities connected by some number of flights. You are given an array flights where flights[i] = [fromi, toi, pricei] indicates that there is a flight from city fromi to city toi with cost pricei.

You are also given three integers src, dst, and k, return the cheapest price from src to dst with at most k stops. If there is no such route, return -1.

Example 1:

Input: n = 4, flights = [[0,1,100],[1,2,100],[2,0,100],[1,3,600],[2,3,200]], src = 0, dst = 3, k = 1
Output: 700
Explanation:
The graph is shown above.
The optimal path with at most 1 stop from city 0 to 3 is marked in red and has cost 100 + 600 = 700.
Note that the path through cities [0,1,2,3] is cheaper but is invalid because it uses 2 stops.

Example 2:

Input: n = 3, flights = [[0,1,100],[1,2,100],[0,2,500]], src = 0, dst = 2, k = 1
Output: 200
Explanation:
The graph is shown above.
The optimal path with at most 1 stop from city 0 to 2 is marked in red and has cost 100 + 100 = 200.

Example 3:

Input: n = 3, flights = [[0,1,100],[1,2,100],[0,2,500]], src = 0, dst = 2, k = 0
Output: 500
Explanation:
The graph is shown above.
The optimal path with no stops from city 0 to 2 is marked in red and has cost 500.

Constraints:

  • 1 <= n <= 100
  • 0 <= flights.length <= (n * (n - 1) / 2)
  • flights[i].length == 3
  • 0 <= fromi, toi < n
  • fromi != toi
  • 1 <= pricei <= 104
  • There will not be any multiple flights between two cities.
  • 0 <= src, dst, k < n
  • src != dst

Approach overview

Problem Overview: You are given n cities connected by flights where each edge has a price. The task is to find the cheapest cost from src to dst using at most k stops. The challenge is balancing shortest-path logic with a constraint on the number of intermediate nodes.

Approach 1: Breadth-First Search with Cost Tracking (Time: O(E * K), Space: O(V + E))

This approach treats the graph as levels of stops and explores it using Breadth-First Search. Build an adjacency list from the flights array, then perform BFS where each level represents one additional stop. Maintain the current cost to each node and only continue exploring if the new path is cheaper than previously recorded costs. The key insight is limiting traversal depth to k + 1 edges while pruning expensive paths early. This keeps exploration efficient even if the graph has many connections.

Approach 2: Dijkstra's Algorithm with Stop Constraint (Time: O(E log (V * K)), Space: O(V * K))

This method adapts shortest path logic using a min-heap (priority queue). Instead of storing only the node and cost, the state also tracks how many stops were used to reach the node. The heap always expands the cheapest path first. When a node is popped, its neighbors are pushed with updated cost and stop count, as long as the stop limit has not been exceeded. This guarantees the cheapest valid route is discovered early and works well when flight graphs are dense.

Recommended for interviews: Interviewers usually expect the Dijkstra-style solution because it directly models the constrained shortest-path problem and demonstrates familiarity with priority queues. Starting with the BFS idea shows you understand graph traversal with level constraints, but implementing the heap-based approach shows stronger mastery of graph optimization techniques.

Approach 1: Breadth-First Search (BFS) with Cost Tracking

In this approach, use BFS to explore all possible paths. Utilize a queue to store the current node, accumulated cost, and the number of stops made so far. The key is to traverse by layer, effectively managing the permitted stops through levels of BFS. If we reach the destination within the allowed stops, track the minimum cost.

from collections import deque, defaultdict

def find_cheapest_price(n, flights, src, dst, k):
    adj_list = defaultdict(list)
    for start, end, price in flights:
        adj_list[start].append((end, price))
    
    # (current city, current cost, remaining stops)
    queue = deque([(src, 0, k + 1)])
    
    min_cost = float('inf')
    
    while queue:
        position, cost, stops = queue.popleft()
        if position == dst:
            min_cost = min(min_cost, cost)
            continue
        if stops > 0:
            for neighbor, price in adj_list[position]:
                if cost + price < min_cost:
                    queue.append((neighbor, cost + price, stops - 1))
    return min_cost if min_cost != float('inf') else -1
function findCheapestPrice(n, flights, src, dst, k) {
    const adjList = {};
    flights.forEach(([start, end, price]) => {
        if (!adjList[start]) adjList[start] = [];
        adjList[start].push([end, price]);
    });
    
    const queue = [[src, 0, k + 1]];
    let minCost = Infinity;
    
    while (queue.length > 0) {
        const [city, cost, stops] = queue.shift();
        if (city === dst) {
            minCost = Math.min(minCost, cost);
            continue;
        }
        if (stops > 0) {
            (adjList[city] || []).forEach(([nextCity, price]) => {
                if (cost + price < minCost) {
                    queue.push([nextCity, cost + price, stops - 1]);
                }
            });
        }
    }
    return minCost === Infinity ? -1 : minCost;
}

This solution constructs a graph from the flights list using an adjacency list. For BFS, a queue keeps track of the current city, the accumulated cost to reach that city, and the number of remaining stops allowed. Traverse each city, and only append a city to the queue if doing so reduces the cost to reach it. This ensures we explore the cheapest path first, within k stops. The process continues until all nodes are explored or the cheapest path is found.

Complexity

Time Complexity: O(n * k) in the worst case when every city is connected.
Space Complexity: O(n) for storing the graph and queue.

Try this approach in the editor

Approach 2: Dijkstra's Algorithm Adaptation

This approach leverages a modified version of Dijkstra's algorithm to explore paths from source to destination using a prioritized data structure like a min-heap. Each entry tracks not only the cumulative cost but also the number of stops taken. The algorithm ensures the shortest paths are evaluated first and skips any path with exceeding stops, thus efficiently finding the minimum cost path within allowed stops.

import java.util.*;

public class Solution {
    public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k) {
        Map<Integer, List<int[]>> adj = new HashMap<>();
        for (int[] f : flights) {
            adj.computeIfAbsent(f[0], x -> new ArrayList<>()).add(new int[]{f[1], f[2]});
        }
        
        PriorityQueue<int[]> heap = new PriorityQueue<>((a, b) -> a[0] - b[0]);
        heap.add(new int[]{0, src, k + 1});
        
        while (!heap.isEmpty()) {
            int[] top = heap.poll();
            int cost = top[0], city = top[1], stops = top[2];
            if (city == dst) return cost;
            if (stops > 0) {
                for (int[] next : adj.getOrDefault(city, Collections.emptyList())) {
                    heap.add(new int[]{cost + next[1], next[0], stops - 1});
                }
            }
        }
        return -1;
    }
}
#include <queue>
#include <vector>
#include <unordered_map>
#include <limits.h>

using namespace std;

int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int k) {
    unordered_map<int, vector<pair<int, int>>> adj;
    for (auto f : flights) {
        adj[f[0]].push_back({f[1], f[2]});
    }
    
    typedef tuple<int, int, int> T;
    priority_queue<T, vector<T>, greater<T>> pq;
    pq.push({0, src, k+1});
    
    while (!pq.empty()) {
        auto [cost, city, stops] = pq.top(); pq.pop();
        if (city == dst) return cost;
        if (stops > 0) {
            for (auto& [nextCity, price] : adj[city]) {
                pq.push({cost + price, nextCity, stops - 1});
            }
        }
    }
    return -1;
}

The Java implementation mirrors the C++ approach, using a priority queue to prioritize lower-cost paths. It explores options similarly: starting from the source, evaluating all connections recursively while updating path costs and stops. By prioritizing by cost, notably using lambda expressions, it ensures the most cost-effective paths are considered first.

Complexity

Time Complexity: O((n+k) log n) characterized by BFS traversal and heap handling.
Space Complexity: O(n), reflecting storage of flights in adjacency lists.

Try this approach in the editor

Approach 3: Default Approach

func findCheapestPrice(n int, flights [][]int, src int, dst int, k int) int {
	const inf = 0x3f3f3f3f
	dist := make([]int, n)
	backup := make([]int, n)
	for i := range dist {
		dist[i] = inf
	}
	dist[src] = 0
	for i := 0; i < k+1; i++ {
		copy(backup, dist)
		for _, e := range flights {
			f, t, p := e[0], e[1], e[2]
			dist[t] = min(dist[t], backup[f]+p)
		}
	}
	if dist[dst] == inf {
		return -1
	}
	return dist[dst]
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Breadth-First Search (BFS) with Cost Tracking

Time Complexity: O(n * k) in the worst case when every city is connected.
Space Complexity: O(n) for storing the graph and queue.

Dijkstra's Algorithm Adaptation

Time Complexity: O((n+k) log n) characterized by BFS traversal and heap handling.
Space Complexity: O(n), reflecting storage of flights in adjacency lists.

Default Approach–

Complexity analysis

ApproachTimeSpaceWhen to Use
BFS with Cost TrackingO(E * K)O(V + E)When the stop limit is small and you want a simple level-based traversal.
Dijkstra with Stop ConstraintO(E log (V * K))O(V * K)General case for weighted graphs where the cheapest path must respect stop limits.

Frequently asked questions

Is Cheapest Flights Within K Stops easy or hard?

Cheapest Flights Within K Stops is classified as a Medium difficulty problem. The challenge comes from combining shortest-path algorithms with a constraint on the number of stops, which requires modifying standard BFS or Dijkstra techniques.

Cheapest Flights Within K Stops Python or Java solution

Python implementations usually use BFS with a deque or Dijkstra with the heapq module. Java solutions typically use a PriorityQueue for the Dijkstra approach and adjacency lists built with ArrayList. Both languages follow the same graph traversal logic with stop constraints.

How to solve Cheapest Flights Within K Stops in O(E*K)?

Use a breadth-first search traversal where each BFS level represents one stop. Maintain a cost array to track the cheapest known price to each city. When exploring neighbors, only update and push them if the new price is lower and the number of stops is within the allowed limit.

What is the best approach for Cheapest Flights Within K Stops?

The most reliable approach is a modified Dijkstra's algorithm using a priority queue. Each state tracks the current city, total cost, and number of stops used. The heap always expands the cheapest route first while ensuring the stop count never exceeds K. This approach runs in roughly O(E log (V*K)) time and works well for dense flight graphs.

Is Cheapest Flights Within K Stops asked at Google/Amazon/Meta?

Cheapest Flights Within K Stops is a common graph interview problem and has appeared in interviews at companies like Amazon and Google. It tests understanding of shortest-path algorithms, BFS level constraints, and priority queue optimizations.

What data structure is used in Cheapest Flights Within K Stops?

The main data structures are an adjacency list for the graph, a queue for the BFS solution, and a min-heap (priority queue) for the Dijkstra-based solution. Arrays or hash maps are also used to track the cheapest cost for each node and stop count.

What is the time complexity of Cheapest Flights Within K Stops?

The BFS with cost tracking approach runs in O(E*K) time because each edge may be explored up to K levels. The Dijkstra-based solution typically runs in O(E log (V*K)) due to heap operations while maintaining states for different stop counts.

Comments

Now write it yourselfClose this page and solve Cheapest Flights Within K Stops in the editor, without looking.
Practise Cheapest Flights Within K Stops