There are n
cities connected by some number of flights. You are given an array flights
where flights[i] = [from<sub>i</sub>, to<sub>i</sub>, price<sub>i</sub>]
indicates that there is a flight from city from<sub>i</sub>
to city to<sub>i</sub>
with cost price<sub>i</sub>
. 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
.
For example:
Given n = 4
, flights = [[0,1,100],[1,2,100],[2,0,100],[1,3,600],[2,3,200]]
, src = 0
, dst = 3
, and k = 1
, the expected output is 700
. The optimal path with at most 1 stop from city 0 to 3 is through city 1, costing 100 + 600 = 700.
Given n = 3
, flights = [[0,1,100],[1,2,100],[0,2,500]]
, src = 0
, dst = 2
, and k = 1
, the expected output is 200
. The optimal path with at most 1 stop from city 0 to 2 is through city 1, costing 100 + 100 = 200.
Given n = 3
, flights = [[0,1,100],[1,2,100],[0,2,500]]
, src = 0
, dst = 2
, and k = 0
, the expected output is 500
. The optimal path with no stops from city 0 to 2 is a direct flight costing 500.
Consider edge cases such as:
src
and dst
are the same?src
to dst
within the given k
stops?Can you implement a solution to find the cheapest price with at most k
stops?
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to finding the cheapest flight within K stops means we explore every possible route from the starting city to the destination, making sure we don't exceed the allowed number of stops. We calculate the cost for each route and keep track of the cheapest one found so far. We examine all feasible paths to find the solution.
Here's how the algorithm would work step-by-step:
def find_cheapest_price_brute_force(number_of_cities,
flights, source_city, destination_city, max_stops):
cheapest_price_found = float('inf')
def depth_first_search(current_city, current_stops,
current_cost, current_path):
nonlocal cheapest_price_found
# If we've reached the destination, update the cheapest price.
if current_city == destination_city:
cheapest_price_found = min(
cheapest_price_found, current_cost)
return
# Prune search if we exceed the maximum allowed stops.
if current_stops > max_stops:
return
for start_city, end_city, price in flights:
if start_city == current_city:
# Avoid cycles by checking if city already in path
if end_city not in current_path:
depth_first_search(
end_city, current_stops + 1,
current_cost + price, current_path + [end_city])
# Start the depth-first search from the source city.
depth_first_search(source_city, 0, 0, [source_city])
# If no path was found, return -1.
if cheapest_price_found == float('inf'):
return -1
else:
return cheapest_price_found
To find the cheapest flight with a limited number of stops, we'll use a modified shortest-path finding technique. Instead of exploring all flight combinations, we smartly track the best known price to reach each city at each number of stops. This helps us avoid re-exploring routes that are already more expensive.
Here's how the algorithm would work step-by-step:
def find_cheapest_price(number_of_cities, flights, source_city, destination_city, max_stops):
cheapest_prices = {}
cheapest_prices[source_city] = 0
# Track costs for each city at each stop count.
for stop_count in range(max_stops + 1):
temp_cheapest_prices = cheapest_prices.copy()
for source, destination, price in flights:
if source in cheapest_prices:
if destination not in temp_cheapest_prices:
temp_cheapest_prices[destination] = float('inf')
# Update price if cheaper path found with current stop count
if cheapest_prices[source] + price < temp_cheapest_prices[destination]:
temp_cheapest_prices[destination] = cheapest_prices[source] + price
cheapest_prices = temp_cheapest_prices
# If destination not reachable, return -1
if destination_city not in cheapest_prices:
return -1
return cheapest_prices[destination_city]
Case | How to Handle |
---|---|
Null or empty flights array | Return -1 immediately since there are no flights to consider, indicating no possible route. |
src and dst are the same city | If source and destination are the same, the price is 0, unless k is negative in which case there is no valid solution so return -1. |
k is 0 and there is no direct flight from src to dst | Return -1 since no stops are allowed and there's no direct flight. |
No path exists between src and dst within k stops | The algorithm should eventually exhaust all possible paths within k stops and return -1 if no path is found. |
Graph contains cycles | The algorithm should avoid infinite loops by limiting the number of stops to k, effectively pruning the search when a cycle is encountered beyond k stops. |
Large number of cities and flights, potentially leading to integer overflow in price calculations | Use long data type or modular arithmetic to prevent integer overflow during price calculations. |
k is very large (close to n-1), potentially causing performance issues | Consider optimizing the algorithm, such as using a priority queue with a visited set, to reduce redundant exploration of less promising paths. |
Flights array contains duplicate flights (same from, to, and price) | The algorithm should handle duplicate flights correctly, treating them as a single flight option. |