There are n cars going to the same destination target miles away. Each car i starts at position[i] with speed speed[i]. A car can never pass another β if it catches up, they form a fleet and travel at the slower car's speed. Return the number of fleets arriving at the target.
Example
Input: target = 12, position = [10,8,0,5,3], speed = [2,4,1,1,3]
Output:3// Car at 10 (ETA 1.0) and car at 8 (ETA 1.0) β fleet// Car at 5 (ETA 7.0) and car at 3 (ETA 3.0) β 3 catches 5, fleet at ETA 7.0// Car at 0 (ETA 12.0) β alone// 3 fleets total
Constraints
β’ n == position.length == speed.lengthβ’ 1 β€ n β€ 10β΅β’ 0 < target β€ 10βΆβ’ All positions are unique
02
Section Two Β· Approach 1
Brute Force β Simulation
Simulate the cars advancing in tiny time steps, merging fleets when a car catches the one ahead. Too slow for large inputs and requires floating-point precision handling.
Problem: Simulation is complex and slow. The key insight: a car's arrival time is (target β position) / speed. Sort by position and compare arrival times β if a behind car arrives sooner or equal, it joins the fleet ahead.
03
Section Three Β· Approach 2
Sort + Stack β O(n log n)
Sort cars by position (closest to target first). Process them in order. Each car's arrival time = (target β position) / speed. If a car's ETA is β€ the car ahead (on the stack), it merges into that fleet. Otherwise, it forms a new fleet.
π‘ Mental model: Imagine watching cars from the finish line. The car closest to you arrives first (or determines the fleet speed). A car behind it that would arrive sooner can't pass β it gets stuck behind and joins the same fleet. Only when a car behind has a later arrival time does it form a new, independent fleet.
Algorithm
Step 1: Pair (position, speed), sort by position descending (closest to target first).
Step 2: For each car, compute ETA = (target β position) / speed.
Step 3: If ETA > stack top β new fleet β push ETA.
Step 4: If ETA β€ stack top β merges into fleet ahead β skip (don't push).
Step 5: Stack size = number of fleets.
π― Key insight:
We only need to compare adjacent cars (sorted by position). A car behind that arrives sooner gets absorbed.
A car behind that arrives later cannot catch the fleet ahead β it starts a new fleet.
import java.util.*;
classSolution {
publicintcarFleet(int target, int[] position, int[] speed) {
int n = position.length;
int[][] cars = newint[n][2];
for (int i = 0; i < n; i++) cars[i] = newint[]{position[i], speed[i]};
Arrays.sort(cars, (a, b) -> b[0] - a[0]); // sort by position descStack<Double> stack = newStack<>();
for (int[] car : cars) {
double eta = (double)(target - car[0]) / car[1];
if (stack.isEmpty() || eta > stack.peek())
stack.push(eta); // new fleet// else: merges into fleet ahead β don't push
}
return stack.size();
}
}
Python β Sort + Stack
classSolution:
defcarFleet(self, target: int, position: list[int], speed: list[int]) -> int:
cars = sorted(zip(position, speed), reverse=True)
stack = []
for pos, spd in cars:
eta = (target - pos) / spd
if not stack or eta > stack[-1]:
stack.append(eta) # new fleetreturn len(stack)
06
Section Six Β· Analysis
Complexity Analysis
Approach
Time
Space
Trade-off
Sort + Stack β optimal
O(n log n)
O(n)
Sort dominates. Stack pass is O(n).
07
Section Seven Β· Edge Cases
Edge Cases & Pitfalls
Case
Input
Why It Matters
Single car
n=1
One car β 1 fleet.
All same speed
spd=[2,2,2]
Nobody catches anyone β n fleets (if sorted differently).
All merge
Closest car slowest
Everyone catches up β 1 fleet.
Same ETA
Two cars with equal ETA
They meet exactly at target β same fleet. Use β€ not <.
β Common Mistake: Sorting by position ascending instead of descending. We must process the car closest to the target first β it's the "blocker." Cars behind it can merge into it, but never pass. Processing from farthest-first would miss fleet merges.