You are given a 0-indexed array of strings garbage
where garbage[i]
represents the assortment of garbage at the i<sup>th</sup>
house. garbage[i]
consists only of the characters 'M'
, 'P'
and 'G'
representing one unit of metal, paper and glass garbage respectively. Picking up one unit of any type of garbage takes 1
minute.
You are also given a 0-indexed integer array travel
where travel[i]
is the number of minutes needed to go from house i
to house i + 1
.
There are three garbage trucks in the city, each responsible for picking up one type of garbage. Each garbage truck starts at house 0
and must visit each house in order; however, they do not need to visit every house.
Only one garbage truck may be used at any given moment. While one truck is driving or picking up garbage, the other two trucks cannot do anything.
Return the minimum number of minutes needed to pick up all the garbage.
For example:
garbage = ["G","P","GP","GG"], travel = [2,4,3]
In this example, the output would be 21. The paper garbage truck travels from house 0 to house 1 (2 minutes), collects the paper garbage at house 1 (1 minute), travels from house 1 to house 2 (4 minutes), and collects the paper garbage at house 2 (1 minute). Altogether, it takes 8 minutes to pick up all the paper garbage.
The glass garbage truck collects the glass garbage at house 0 (1 minute), travels from house 0 to house 1 (2 minutes), travels from house 1 to house 2 (4 minutes), collects the glass garbage at house 2 (1 minute), travels from house 2 to house 3 (3 minutes), and collects the glass garbage at house 3 (2 minutes). Altogether, it takes 13 minutes to pick up all the glass garbage.
Since there is no metal garbage, we do not need to consider the metal garbage truck. Therefore, it takes a total of 8 + 13 = 21 minutes to collect all the garbage.
Can you provide an efficient algorithm to solve this problem?
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 means we'll try every single possible path the garbage trucks can take. We will calculate the total time for each path and then pick the one that takes the least amount of time.
Here's how the algorithm would work step-by-step:
import itertools
def minimum_time_to_collect_garbage_brute_force(garbage, travel):
shortest_time = float('inf')
number_of_houses = len(garbage)
# Generate all possible orderings of houses
for house_ordering in itertools.permutations(range(number_of_houses)):
total_time_for_ordering = 0
# Iterate through each type of garbage
for garbage_type in ['M', 'P', 'G']:
time_for_this_garbage = 0
current_house_index = 0
last_house_with_garbage = -1
# Find the last house with this type of garbage
for i in range(number_of_houses):
if garbage_type in garbage[house_ordering[i]]:
last_house_with_garbage = i
if last_house_with_garbage == -1:
continue
# Calculate time to collect garbage from each house.
for i in range(number_of_houses):
house_index_in_ordering = i
if garbage_type in garbage[house_ordering[i]]:
time_for_this_garbage += garbage[house_ordering[i]].count(garbage_type)
# Calculate travel time to the next house. Stop at last house
if i < last_house_with_garbage:
travel_index = min(house_ordering[i],house_ordering[i+1])
travel_index_two = max(house_ordering[i],house_ordering[i+1])
houses_between = travel_index_two-travel_index
# Travel time is calculated
for j in range(travel_index,travel_index_two):
time_for_this_garbage += travel[j]
# Add up travel and garbage collection time
total_time_for_ordering += time_for_this_garbage
# Keep track of the shortest time
shortest_time = min(shortest_time, total_time_for_ordering)
return shortest_time
The key to solving this efficiently is to realize we only need to visit each house once for each garbage type. We can precompute the last house each garbage truck needs to visit and the total garbage of each type. Then, for each garbage type, we simply add up the travel time to the last house and the amount of garbage of that type.
Here's how the algorithm would work step-by-step:
def minimum_garbage_collection_time(garbage, travel):
last_house_metal = 0
last_house_paper = 0
last_house_glass = 0
total_metal = 0
total_paper = 0
total_glass = 0
for i in range(len(garbage)):
if 'M' in garbage[i]:
last_house_metal = i
total_metal += garbage[i].count('M')
if 'P' in garbage[i]:
last_house_paper = i
total_paper += garbage[i].count('P')
if 'G' in garbage[i]:
last_house_glass = i
total_glass += garbage[i].count('G')
travel_time_metal = 0
travel_time_paper = 0
travel_time_glass = 0
# Calculate travel time to the last house for each garbage type
for i in range(last_house_metal):
travel_time_metal += travel[i]
for i in range(last_house_paper):
travel_time_paper += travel[i]
for i in range(last_house_glass):
travel_time_glass += travel[i]
# Sum garbage collection time and travel time for each type
total_time_metal = total_metal + travel_time_metal
total_time_paper = total_paper + travel_time_paper
total_time_glass = total_glass + travel_time_glass
# Add up all the times to get the final result.
total_time = total_time_metal + total_time_paper + total_time_glass
return total_time
Case | How to Handle |
---|---|
Null or empty garbage array | Return 0 immediately, as no garbage needs collection. |
Null or empty travel array | If garbage array is not empty, treat travel as if it had zero travel time for all trucks. |
Garbage array with only one string | Calculate the time to collect that single garbage string plus travel time if not the first house. |
Travel array shorter than the number of houses with garbage | Assume zero travel time for houses beyond the defined travel array size, essentially staying at the last valid house. |
Garbage array containing empty strings | Treat empty strings as houses with no garbage of that type, skipping collection for that specific truck type at that house. |
Travel array containing very large travel times | Ensure integer overflow doesn't occur when summing travel times; use appropriate data types (e.g., long). |
Garbage array with all garbage of only one type | Only the truck corresponding to that garbage type is needed, and the algorithm should correctly compute the travel time. |
Houses with no garbage, represented by empty strings in the garbage array. | The algorithm should skip these houses when calculating the travel distance for each garbage truck, avoiding unnecessary travel. |