Cheapest Flight within k Stops


Link : Cheapest Flights Within K Stops


Problem Statement

You are given:

Goal

Return the cheapest price from src to dst with at most k stops.
If no such route exists, return -1.


Examples

Example 1

Input:
n = 4
flights = [[0,1,100],[1,2,100],[2,3,100],[0,3,500]]
src = 0, dst = 3, k = 1

Output:
500

Explanation:
- You can go directly from 0 to 3 with cost 500 (0 stops)
- Or 0 → 1 → 2 → 3 with cost 300 (2 stops), which is invalid since it exceeds k=1

Example 2

Input:
n = 3
flights = [[0,1,100],[1,2,100],[0,2,500]]
src = 0, dst = 2, k = 1

Output:
200

Explanation:
- 0 → 1 → 2 (1 stop) with total cost = 200

Why Not Use Dijkstra?

In Dijkstra's algorithm, once we visit a node, we typically don't revisit it.
But in this problem, a cheaper route to a node might be found through another path that uses fewer or more stops.

Therefore, we use a variation of BFS known as Dijkstra with constraints or Bellman-Ford-like BFS.


Approach: Modified BFS (Dijkstra-like with Queue)

We use a priority queue (or normal queue) and track:

We prune paths if:


Java Code (Using PriorityQueue)

class Solution {
    class Pair {
        int node, cost, stops;
        Pair(int node, int cost, int stops) {
            this.node = node;
            this.cost = cost;
            this.stops = stops;
        }
    }

    public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k) {
        // Build adjacency list
        Map<Integer, List<int[]>> adj = new HashMap<>();
        for (int[] flight : flights) {
            adj.computeIfAbsent(flight[0], x -> new ArrayList<>()).add(new int[]{flight[1], flight[2]});
        }

        // Min-heap: compare based on cost
        PriorityQueue<Pair> pq = new PriorityQueue<>((a, b) -> a.cost - b.cost);
        pq.add(new Pair(src, 0, 0));

        int[] minStops = new int[n];
        Arrays.fill(minStops, Integer.MAX_VALUE);
        minStops[src] = 0;

        while (!pq.isEmpty()) {
            Pair cur = pq.poll();
            int node = cur.node;
            int cost = cur.cost;
            int stops = cur.stops;

            if (node == dst) return cost;

            if (stops > k || stops > minStops[node]) continue;
            minStops[node] = stops;

            if (!adj.containsKey(node)) continue;

            for (int[] neighbor : adj.get(node)) {
                int nextNode = neighbor[0];
                int weight = neighbor[1];
                pq.add(new Pair(nextNode, cost + weight, stops + 1));
            }
        }

        return -1;
    }
}

Dry Run

Input

n = 3
flights = [[0,1,100],[1,2,100],[0,2,500]]
src = 0, dst = 2, k = 1

Step-by-Step Execution

Final answer: 200


Time and Space Complexity

Time Complexity

Space Complexity


Alternative: Bellman-Ford (K Iterations)

Use dynamic programming or Bellman-Ford idea to relax edges k + 1 times.

Pros


Why PriorityQueue Over Queue?


Why Not TreeSet?


Conclusion