Skip to content

Commit 22ffbd4

Browse files
committed
feat(algorithms, greedy): min number of refueling stops
1 parent 80c3de0 commit 22ffbd4

21 files changed

Lines changed: 193 additions & 0 deletions
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Minimum Number of Refueling Stops
2+
3+
You need to find the minimum number of refueling stops that a car needs to make to cover a distance, target. For
4+
simplicity, assume that the car has to travel from west to east in a straight line. There are various fuel stations on
5+
the way that are represented as a 2-D array of stations, i.e., stations[i]=[di,fi], where di is the distance (in miles)
6+
of the ith gas station from the starting position, and fi is the amount of fuel (in liters) that it stores. Initially,
7+
the car starts with k liters of fuel. The car consumes one liter of fuel for every mile traveled. Upon reaching a gas
8+
station, the car can stop and refuel using all the petrol stored at the station. If it cannot reach the target, the
9+
program returns −1.
10+
11+
> Note: If the car reaches a station with 0 fuel left, it can refuel from that station, and all the fuel from that
12+
> station can be transferred to the car. If the car reaches the target with 0 fuel left, it is still considered to have
13+
> arrived.
14+
15+
## Constraints
16+
17+
- 1 <= `target`, `k` <= 10^9
18+
- 0 <= `stations.length`, <= 900
19+
- 1 <= di < di+1 < `target`
20+
- 1 <= fi < 10^9
21+
22+
## Examples
23+
24+
![Example 1](./images/examples/minimum_number_of_refueling_stops_example_1.png)
25+
![Example 2](./images/examples/minimum_number_of_refueling_stops_example_2.png)
26+
![Example 3](./images/examples/minimum_number_of_refueling_stops_example_3.png)
27+
![Example 4](./images/examples/minimum_number_of_refueling_stops_example_4.png)
28+
![Example 5](./images/examples/minimum_number_of_refueling_stops_example_5.png)
29+
![Example 6](./images/examples/minimum_number_of_refueling_stops_example_6.png)
30+
![Example 7](./images/examples/minimum_number_of_refueling_stops_example_7.png)
31+
![Example 8](./images/examples/minimum_number_of_refueling_stops_example_8.png)
32+
33+
## Solutions
34+
35+
### Using Max Heap
36+
37+
This problem can be solved using the greedy algorithm, since the car has to reach the destination using a minimum number
38+
of refueling stops. This means that the car needs a maximum fuel amount at any point. The idea is to make optimal choices
39+
by selecting the fuel station with the maximum fuel capacity at each step to reach the target distance with the minimum
40+
number of refueling stops.
41+
42+
To cater to the problem of selecting the maximum fuel value, we can use the max-heap to keep track of fuel capacity for
43+
refueling because the top of the max-heap will always have the highest fuel value. Therefore we can take the highest fuel
44+
value from the top of the max-heap to reach the target by using the minimum number of refueling stops. To implement this
45+
methodology, we will create a function, min_refuel_stops. The steps of the function are given below:
46+
47+
1. If the starting fuel is greater than or equal to the target distance, return 0. It means no extra fuel is required,
48+
and the car can reach the target using the starting fuel.
49+
2. Otherwise, iterate until the maximum distance is equal to or greater than the target, and the car is not out of fuel:
50+
- If we have a fuel station that can be used to refuel, and the vehicle has enough fuel to reach it, add the refueling
51+
station to the max-heap.
52+
- If the max-heap contains no fuel stations, the vehicle can’t reach the target, and the function returns −1. In
53+
simpler words, the car doesn’t have enough fuel to reach the target even after stopping at all the fuel stations.
54+
- Otherwise, if the max-heap has fuel stations and the vehicle doesn’t have enough fuel to go to the next station,
55+
the vehicle refuels from the fuel station with the maximum fuel value. After refueling, we remove the fuel value of
56+
this refueling station from the max-heap and also increment the number of stops.
57+
3. After executing the loop, the function returns the total number of refueling stops required to reach the target
58+
distance.
59+
60+
![Solution 1](./images/solutions/minimum_number_of_refueling_stops_solution_max_heap_1.png)
61+
![Solution 2](./images/solutions/minimum_number_of_refueling_stops_solution_max_heap_2.png)
62+
![Solution 3](./images/solutions/minimum_number_of_refueling_stops_solution_max_heap_3.png)
63+
![Solution 4](./images/solutions/minimum_number_of_refueling_stops_solution_max_heap_4.png)
64+
![Solution 5](./images/solutions/minimum_number_of_refueling_stops_solution_max_heap_5.png)
65+
![Solution 6](./images/solutions/minimum_number_of_refueling_stops_solution_max_heap_6.png)
66+
![Solution 7](./images/solutions/minimum_number_of_refueling_stops_solution_max_heap_7.png)
67+
![Solution 8](./images/solutions/minimum_number_of_refueling_stops_solution_max_heap_8.png)
68+
![Solution 9](./images/solutions/minimum_number_of_refueling_stops_solution_max_heap_9.png)
69+
![Solution 10](./images/solutions/minimum_number_of_refueling_stops_solution_max_heap_10.png)
70+
71+
#### Time Complexity
72+
73+
The time complexity of the solution above is O(n×log(n)), where n is the total number of stations.
74+
75+
#### Space Complexity
76+
77+
The space complexity of the solution above is O(n), since there will be maximum n fuel capacities in a heap.
78+
79+
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
from typing import List
2+
import heapq
3+
4+
5+
def min_refuel_stops(target: int, start_fuel: int, stations: List[List[int]]):
6+
# if the start fuel is 0, we can't start the journey
7+
if start_fuel == 0:
8+
return -1
9+
10+
# No need to stop to refuel, the car can reach the target distance with the starting fuel
11+
if start_fuel >= target:
12+
return 0
13+
14+
# Create a max heap to store the fuel capacities of stations in
15+
# such a way that maximum fuel capacity is at the top of the heap
16+
max_heap = []
17+
i, n = 0, len(stations)
18+
# This will keep track of the minimum refueling stops
19+
min_stops = 0
20+
max_distance = start_fuel
21+
22+
# loop until the car reaches the target, or it is out of fuel
23+
while max_distance < target:
24+
# If there are still stations and the next one is within range, add its fuel capacity to the max heap
25+
if i < n and stations[i][0] <= max_distance:
26+
heapq.heappush(max_heap, -stations[i][1])
27+
i += 1
28+
# If there are no more stations, and we can't reach the target, return -1
29+
elif not max_heap:
30+
return -1
31+
else:
32+
# Otherwise, fill up at the station with the highest fuel capacity and increment stops
33+
max_distance += -heapq.heappop(max_heap)
34+
min_stops += 1
35+
36+
return min_stops
37+
38+
39+
def min_refuel_stops_2(target: int, start_fuel: int, stations: List[List[int]]):
40+
# if the start fuel is 0, we can't start the journey
41+
if start_fuel == 0:
42+
return -1
43+
44+
# No need to stop to refuel, the car can reach the target distance with the starting fuel
45+
if start_fuel >= target:
46+
return 0
47+
48+
max_heap = []
49+
50+
# Append target to stations to treat final destination as station with no fuel
51+
stations.append([target, 0])
52+
53+
# This will keep track of the minimum refueling stops
54+
min_stops = 0
55+
# Keeps track of the distance covered from the start. This will be used to calculate the distance to the next station
56+
distance_covered = 0
57+
# Current fuel level is the current fuel level we have
58+
current_fuel_level = start_fuel
59+
60+
for idx in range(len(stations)):
61+
station_distance, station_fuel = stations[idx]
62+
# The Fuel cost is the station distance from the beginning minus the distance covered so far
63+
fuel_cost = station_distance - distance_covered
64+
65+
current_fuel_level -= fuel_cost
66+
67+
while current_fuel_level < 0 and max_heap:
68+
current_fuel_level -= heapq.heappop(max_heap)
69+
min_stops += 1
70+
71+
# check if we can reach the next station
72+
if current_fuel_level < 0:
73+
return -1
74+
75+
heapq.heappush(max_heap, -station_fuel)
76+
distance_covered = station_distance
77+
78+
return min_stops
23.4 KB
Loading
30.7 KB
Loading
31.6 KB
Loading
44.7 KB
Loading
40.1 KB
Loading
43.4 KB
Loading
47 KB
Loading
54.7 KB
Loading

0 commit comments

Comments
 (0)