🧠
Brute Force (DFS with Stops Limit)
💡 This approach tries all possible flight paths up to K stops recursively. It is the foundation to understand the problem but is inefficient due to repeated computations.
Intuition
Try every possible flight path from source to destination with at most K stops, keeping track of the cost and updating the minimum.
Algorithm
- Start DFS from source city with 0 stops and 0 cost.
- At each city, if destination reached, update minimum cost.
- If stops exceed K, backtrack.
- Explore all outgoing flights recursively.
💡 The recursion tree grows exponentially because each city can lead to multiple next cities, making it hard to track all paths without pruning.
Recurrence:cost(city, stops) = min over all next cities { cost(next_city, stops+1) + flight_cost }
from collections import defaultdict
import sys
def findCheapestPrice(n, flights, src, dst, K):
graph = defaultdict(list)
for u,v,w in flights:
graph[u].append((v,w))
min_cost = [sys.maxsize]
def dfs(city, stops, cost):
if stops > K + 1 or cost > min_cost[0]:
return
if city == dst:
min_cost[0] = cost
return
for nei, price in graph[city]:
dfs(nei, stops + 1, cost + price)
dfs(src, 0, 0)
return min_cost[0] if min_cost[0] != sys.maxsize else -1
# Example usage
if __name__ == '__main__':
n = 3
flights = [[0,1,100],[1,2,100],[0,2,500]]
src = 0
dst = 2
K = 1
print(findCheapestPrice(n, flights, src, dst, K)) # Output: 200
Line Notes
graph = defaultdict(list)Build adjacency list for quick access to neighbors
for u,v,w in flightsPopulate graph edges with costs
min_cost = [sys.maxsize]Use list to allow modification inside dfs closure
if stops > K + 1 or cost > min_cost[0]Prune paths exceeding stops or already more expensive
if city == dstUpdate minimum cost when destination reached
for nei, price in graph[city]Explore all neighbors recursively
dfs(src, 0, 0)Start DFS from source with zero stops and cost
import java.util.*;
public class Solution {
private int minCost = Integer.MAX_VALUE;
private Map<Integer, List<int[]>> graph = new HashMap<>();
public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) {
for (int[] f : flights) {
graph.computeIfAbsent(f[0], k -> new ArrayList<>()).add(new int[]{f[1], f[2]});
}
dfs(src, dst, K + 1, 0);
return minCost == Integer.MAX_VALUE ? -1 : minCost;
}
private void dfs(int city, int dst, int stops, int cost) {
if (stops < 0 || cost > minCost) return;
if (city == dst) {
minCost = cost;
return;
}
if (!graph.containsKey(city)) return;
for (int[] next : graph.get(city)) {
dfs(next[0], dst, stops - 1, cost + next[1]);
}
}
public static void main(String[] args) {
Solution sol = new Solution();
int n = 3;
int[][] flights = {{0,1,100},{1,2,100},{0,2,500}};
int src = 0, dst = 2, K = 1;
System.out.println(sol.findCheapestPrice(n, flights, src, dst, K)); // 200
}
}
Line Notes
private int minCost = Integer.MAX_VALUE;Track minimum cost globally
graph.computeIfAbsent(f[0], k -> new ArrayList<>())Build adjacency list
dfs(src, dst, K + 1, 0);Start DFS with allowed flights = K+1
if (stops < 0 || cost > minCost) return;Prune invalid or expensive paths
if (city == dst)Update minCost when destination reached
for (int[] next : graph.get(city))Explore neighbors recursively
public static void mainDriver code to test example
#include <iostream>
#include <vector>
#include <unordered_map>
#include <climits>
using namespace std;
class Solution {
int minCost = INT_MAX;
unordered_map<int, vector<pair<int,int>>> graph;
void dfs(int city, int dst, int stops, int cost) {
if (stops < 0 || cost > minCost) return;
if (city == dst) {
minCost = cost;
return;
}
if (graph.find(city) == graph.end()) return;
for (auto &next : graph[city]) {
dfs(next.first, dst, stops - 1, cost + next.second);
}
}
public:
int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
for (auto &f : flights) {
graph[f[0]].push_back({f[1], f[2]});
}
dfs(src, dst, K + 1, 0);
return minCost == INT_MAX ? -1 : minCost;
}
};
int main() {
Solution sol;
vector<vector<int>> flights = {{0,1,100},{1,2,100},{0,2,500}};
cout << sol.findCheapestPrice(3, flights, 0, 2, 1) << endl; // 200
return 0;
}
Line Notes
unordered_map<int, vector<pair<int,int>>> graph;Adjacency list for flights
if (stops < 0 || cost > minCost) return;Prune invalid or costly paths
if (city == dst)Update minCost when destination reached
for (auto &next : graph[city])Explore all neighbors recursively
dfs(src, dst, K + 1, 0);Start DFS with K+1 flights allowed
return minCost == INT_MAX ? -1 : minCost;Return -1 if no route found
function findCheapestPrice(n, flights, src, dst, K) {
const graph = new Map();
for (const [u,v,w] of flights) {
if (!graph.has(u)) graph.set(u, []);
graph.get(u).push([v,w]);
}
let minCost = Infinity;
function dfs(city, stops, cost) {
if (stops > K + 1 || cost > minCost) return;
if (city === dst) {
minCost = cost;
return;
}
if (!graph.has(city)) return;
for (const [next, price] of graph.get(city)) {
dfs(next, stops + 1, cost + price);
}
}
dfs(src, 0, 0);
return minCost === Infinity ? -1 : minCost;
}
// Example usage
console.log(findCheapestPrice(3, [[0,1,100],[1,2,100],[0,2,500]], 0, 2, 1)); // 200
Line Notes
const graph = new Map();Build adjacency list for flights
if (!graph.has(u)) graph.set(u, []);Initialize adjacency list entry
let minCost = Infinity;Track minimum cost globally
if (stops > K + 1 || cost > minCost) return;Prune invalid or expensive paths
if (city === dst)Update minCost when destination reached
for (const [next, price] of graph.get(city))Explore neighbors recursively
dfs(src, 0, 0);Start DFS from source
TimeO(n^(K+1))
SpaceO(n) for recursion stack
Each city can lead to multiple next cities, and recursion depth is up to K+1 flights, leading to exponential paths.
💡 For n=3 and K=1, this means exploring up to 3^2=9 paths, which is manageable, but for larger n and K it quickly becomes infeasible.
Interview Verdict: TLE
This approach is too slow for large inputs but is useful to understand the problem and build towards DP.