class Solution:
def eliminateMaximum(self, dist, speed):
# Calculate the time each monster reaches the city
times = [(d - 1) // s + 1 for d, s in zip(dist, speed)]
times.sort()
for minute, t in enumerate(times):
if t <= minute:
return minute
return len(dist)
class Solution {
public:
int eliminateMaximum(vector<int>& dist, vector<int>& speed) {
int n = dist.size();
vector<int> times(n);
for (int i = 0; i < n; ++i) {
times[i] = (dist[i] - 1) / speed[i] + 1;
}
sort(times.begin(), times.end());
for (int minute = 0; minute < n; ++minute) {
if (times[minute] <= minute) return minute;
}
return n;
}
};
class Solution {
public int eliminateMaximum(int[] dist, int[] speed) {
int n = dist.length;
int[] times = new int[n];
for (int i = 0; i < n; ++i) {
times[i] = (dist[i] - 1) / speed[i] + 1;
}
Arrays.sort(times);
for (int minute = 0; minute < n; ++minute) {
if (times[minute] <= minute) return minute;
}
return n;
}
}
var eliminateMaximum = function(dist, speed) {
let times = dist.map((d, i) => Math.floor((d - 1) / speed[i]) + 1);
times.sort((a, b) => a - b);
for (let minute = 0; minute < times.length; ++minute) {
if (times[minute] <= minute) return minute;
}
return times.length;
};
You are given two integer arrays, dist
and speed
, both of length n
. Each element dist[i]
represents the initial distance of the i
-th monster from the city, and speed[i]
represents the speed at which the i
-th monster is approaching.
Every minute, you can eliminate exactly one monster before any of them move. At the end of each minute, all remaining monsters move towards the city according to their speed. If any monster reaches the city (distance ≤ 0), the game ends immediately.
Your task is to determine the maximum number of monsters you can eliminate before any monster reaches the city.
Let's break down the problem. We need to eliminate as many monsters as possible before any of them reaches the city. Each minute, we can only eliminate one monster, and after that, all remaining monsters move closer.
A brute-force approach would be to simulate each minute, checking all monsters' positions and deciding which one to eliminate. But this quickly becomes inefficient, especially with larger inputs.
To optimize, we need to focus on the most urgent threats: the monsters that will reach the city first. If we always eliminate the monster that is closest to arriving, we delay the loss for as long as possible. Thus, we should sort monsters by their "arrival time" (how many minutes until each reaches the city) and eliminate in that order.
The key insight is: the monster with the earliest arrival time is always the biggest threat. If we can't eliminate that monster before it arrives, the game ends.
ceil(dist[i] / speed[i])
. Since we eliminate before monsters move, we can use integer math: (dist[i] - 1) // speed[i] + 1
.
This algorithm is efficient because sorting the arrival times allows us to process monsters in the order of urgency, ensuring we always make the optimal elimination choice.
Let's use dist = [1,3,4]
and speed = [1,1,1]
as an example.
If instead, the input was dist = [1,1,2,3]
, speed = [1,1,1,1]
, arrival times would be [1,1,2,3]. At minute 0, eliminate one monster with arrival 1; at minute 1, the next monster with arrival 1 has already reached the city, so the answer is 1.
The optimized approach is much more efficient, especially for large numbers of monsters.
In summary, the problem is best solved by focusing on each monster's arrival time, sorting these times, and always eliminating the monster that is closest to arriving. This greedy strategy ensures that you always maximize the number of monsters eliminated before the city is breached. The approach is both simple and efficient, relying on sorting and a single pass through the sorted list, making it well-suited for large input sizes.