You are playing a video game where you are defending your city from a group of n
monsters. You are given a 0-indexed integer array dist
of size n
, where dist[i]
is the initial distance in kilometers of the ith
monster from the city.
The monsters walk toward the city at a constant speed. The speed of each monster is given to you in an integer array speed
of size n
, where speed[i]
is the speed of the ith
monster in kilometers per minute.
You have a weapon that, once fully charged, can eliminate a single monster. However, the weapon takes one minute to charge. The weapon is fully charged at the very start.
You lose when any monster reaches your city. If a monster reaches the city at the exact moment the weapon is fully charged, it counts as a loss, and the game ends before you can use your weapon.
Return the maximum number of monsters that you can eliminate before you lose, or n
if you can eliminate all the monsters before they reach the city.
Example 1:
Input: dist = [1,3,4], speed = [1,1,1] Output: 3 Explanation: In the beginning, the distances of the monsters are [1,3,4]. You eliminate the first monster. After a minute, the distances of the monsters are [X,2,3]. You eliminate the second monster. After a minute, the distances of the monsters are [X,X,2]. You eliminate the third monster. All 3 monsters can be eliminated.
Example 2:
Input: dist = [1,1,2,3], speed = [1,1,1,1] Output: 1 Explanation: In the beginning, the distances of the monsters are [1,1,2,3]. You eliminate the first monster. After a minute, the distances of the monsters are [X,0,1,2], so you lose. You can only eliminate 1 monster.
Example 3:
Input: dist = [3,2,4], speed = [5,3,2] Output: 1 Explanation: In the beginning, the distances of the monsters are [3,2,4]. You eliminate the first monster. After a minute, the distances of the monsters are [X,0,2], so you lose. You can only eliminate 1 monster.
Constraints:
n == dist.length == speed.length
1 <= n <= 105
1 <= dist[i], speed[i] <= 105
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 involves simulating every possible scenario of fighting the monsters. We try different orders of shooting the monsters to figure out the best strategy. This means checking all possible combinations of monster takedowns to see which one lets us defeat the most monsters before they reach the city.
Here's how the algorithm would work step-by-step:
import itertools
def eliminate_maximum_number_of_monsters(
distances_to_city, monster_speeds
):
number_of_monsters = len(distances_to_city)
maximum_monsters_eliminated = 0
# Iterate through all possible monster shooting orders
for shooting_order in itertools.permutations(range(number_of_monsters)):
monsters_eliminated = 0
time = 0
can_eliminate = True
# Simulate the game with the current shooting order
for monster_index in shooting_order:
arrival_time = (
distances_to_city[monster_index] /
monster_speeds[monster_index]
)
# Check if monster reaches the city before being shot
if arrival_time <= time:
can_eliminate = False
break
# Increment time after shooting a monster
time += 1
monsters_eliminated += 1
# Update maximum monsters eliminated if needed
if can_eliminate:
maximum_monsters_eliminated = max(
maximum_monsters_eliminated, monsters_eliminated
)
return maximum_monsters_eliminated
The problem asks us to maximize the number of monsters we eliminate. A key insight is to realize we should prioritize eliminating monsters that will reach the city sooner rather than later. By strategically eliminating the closest monsters first, we can defend the city for as long as possible.
Here's how the algorithm would work step-by-step:
def eliminate_maximum_number_of_monsters(distances, speeds):
number_of_monsters = len(distances)
arrival_times = []
for i in range(number_of_monsters):
arrival_times.append(float(distances[i]) / speeds[i])
# Sort monsters based on arrival time to prioritize early threats.
arrival_times.sort()
eliminated_count = 0
time = 0
for arrival_time in arrival_times:
# Check if we have time to eliminate the monster before it arrives.
if arrival_time <= time:
break
# Increment eliminated count since we can eliminate the monster.
eliminated_count += 1
time += 1
return eliminated_count
Case | How to Handle |
---|---|
Empty dist or speed arrays | Return 0 immediately since there are no monsters to eliminate. |
dist and speed arrays of different lengths | Throw an IllegalArgumentException or return an error code, indicating invalid input. |
Zero distance for a monster | The time to reach the city is 0, so eliminate it immediately if possible. |
Zero speed for a monster | If distance is also zero, handle as above; otherwise, the monster never reaches the city, so don't count it. |
Large dist and speed values causing potential integer overflow | Use long data type to store the time to reach the city to prevent overflow. |
Monsters all arrive at the same time | The algorithm should correctly eliminate monsters in the order they appear in the input. |
No monsters can be eliminated | Return 0 indicating that no monsters could be eliminated before being overtaken. |
Very large n (size of dist/speed arrays) | Ensure the sorting algorithm used to determine arrival times has O(n log n) complexity for acceptable performance. |