How to Explain Car Fleet in a Coding Interview (Step-by-Step)
Car Fleet is deceptively tricky — it reads like a simulation problem but solves cleanly as a monotonic stack on arrival times. The key insight isn’t about physics; it’s about recognising that a faster car behind a slower car will always be blocked, and that the stack lets you track that blocking relationship in a single pass.
In this post, you’ll learn exactly how to walk an interviewer through LeetCode 853: why you sort by position descending, how to compute arrival times, the fleet-merging logic, and every edge case worth naming.
Problem Statement
There are n cars at given positions on a single-lane road heading toward a target. Each car i has position position[i] and speed speed[i]. A car cannot pass another car ahead of it — it can only catch up and form a fleet (group travelling together at the slower car’s speed).
Return the number of car fleets that will arrive at the target.
Examples
Output: 3
Explanation: The cars at positions 10 and 8 become one fleet.
The car at position 0 forms its own fleet.
The cars at positions 5 and 3 become one fleet.
Output: 1
Output: 1
Explanation: All three cars eventually catch up and merge into one fleet.
Constraints
n == position.length == speed.length1 <= n <= 1050 < target <= 1060 <= position[i] < target- All positions are unique
0 < speed[i] <= 106
What Is the Problem?
“Cars travel on a single lane toward a target — no passing allowed. A faster car behind a slower one will catch up and then travel at the slower speed as one fleet. I need to count how many distinct fleets arrive at the target. The key observation is that a car can only be blocked by a car that is ahead of it — so I should process cars from closest to the target first.”
Stating the no-passing rule and the direction of blocking upfront shows the interviewer you’ve identified the physical constraint that drives the entire solution.
Step 1: Compare Approaches Before Jumping to Code
“There is no need to simulate. The question of how many fleets arrive is entirely determined by arrival times. If a car behind arrives at the target no later than the car ahead, it will have caught up — they form one fleet. Sorting by position descending lets me process cars from front to back and compare each car to the fleet immediately ahead of it.”
The Key Insight — Arrival Times Determine Fleets
For each car, compute its arrival time if it travelled unobstructed: time = (target − position) / speed.
Now sort cars by position descending (closest to target first). Process them in this order. Maintain a stack of fleet arrival times. For each car:
If its arrival time is greater than the top of the stack, it can never catch the fleet ahead — it becomes a new independent fleet. Push it.
If its arrival time is less than or equal to the top, it would catch up before or at the target — it merges into the leading fleet. Do not push.
The number of fleets is the size of the stack at the end.
“The word ‘unobstructed’ is critical — I compute arrival time assuming no car is in the way. If this theoretical time is still slower than the car ahead, it will never catch up even with free road. If it’s faster or equal, it catches up exactly at or before the target and joins the fleet. Fleets travel together, so only the slowest (first-pushed) time per fleet is what future cars compare against.”
Step 2: Explain the Algorithm in Plain English
Zip position and speed together. Sort by position in descending order — closest car to target is processed first. This is the only sorting step; it costs O(n log n).
For car at position p with speed s: time = (target − p) / s. A higher time means the car is slower or farther back — it arrives later.
For each car (front to back), if the stack is empty or the car’s arrival time is strictly greater than the stack top, it forms a new fleet — push its time. Otherwise, it merges into the fleet ahead — skip it (do not push).
Each element on the stack represents one distinct fleet. Return len(stack).
Fleet Merging Visualised — target=12, position=[10,8,0,5,3], speed=[2,4,1,1,3]
First, compute each car’s arrival time and sort by position descending:
| Position | Speed | Distance to target | Arrival time | Fleet outcome |
|---|---|---|---|---|
| 10 | 2 | 12−10 = 2 | 2/2 = 1.0 | New fleet (stack empty) |
| 8 | 4 | 12−8 = 4 | 4/4 = 1.0 | Merge — 1.0 ≤ stack top 1.0 |
| 5 | 1 | 12−5 = 7 | 7/1 = 7.0 | New fleet — 7.0 > stack top 1.0 |
| 3 | 3 | 12−3 = 9 | 9/3 = 3.0 | Merge — 3.0 ≤ stack top 7.0 |
| 0 | 1 | 12−0 = 12 | 12/1 = 12.0 | New fleet — 12.0 > stack top 7.0 |
Stack at the end: [1.0, 7.0, 12.0] → 3 fleets ✓
“Car at position 8 has arrival time 1.0 — same as car at position 10. Even though car 8 is faster, it can’t pass car 10. It catches up exactly at the target and merges. Car at position 3 has arrival time 3.0 which is less than 7.0 (the fleet at position 5), so it catches that fleet before the target and merges.”
Stack Trace Step by Step
Step 3: Talk Through the Code
class Solution:
def carFleet(self, target: int, position: List[int], speed: List[int]) -> int:
# Pair cars and sort by position descending (closest to target first)
cars = sorted(zip(position, speed), key=lambda x: -x[0])
stack = [] # Stores arrival times of distinct fleets
for pos, spd in cars:
time = (target - pos) / spd # Unobstructed arrival time
# A new fleet forms only if this car arrives AFTER the fleet ahead
# (i.e. it can never catch up, even on an open road)
if not stack or time > stack[-1]:
stack.append(time)
# else: time <= stack[-1] → car catches up → merges, do nothing
return len(stack)
Draw attention to the condition time > stack[-1] — strictly greater than. Equal arrival time means the car catches up exactly at the target and still merges. Using >= here would over-count fleets. This is the most common off-by-one mistake on this problem.
Step 4: Highlight Edge Cases
"One car, no cars ahead. Stack starts empty, the car's time is pushed immediately. Stack size = 1 → return 1. Correct."
"Arrival times are proportional to distance. Cars closer to the target arrive earlier. No car behind can catch the one ahead since they travel at the same speed and are at different starting positions — each becomes its own fleet. Stack size = n."
"Sorted by position desc: (4,1), (2,2), (0,4). Times: 96, 49, 24. Car at pos 2 has time 49 < 96 → merges. Car at pos 0 has time 24 < 96 → merges. Stack = [96], size = 1. One fleet."
"Equal arrival time means the car behind catches up exactly at the target. The condition is time > stack[-1] — equal does not push. They form one fleet. This is why strictly greater-than, not greater-than-or-equal, is the correct condition."
"If every car has a strictly greater arrival time than the one ahead, no merging occurs. Every car forms its own fleet. Stack size = n."
Step 5: State Time and Space Complexity
| Dimension | Complexity | Reason |
|---|---|---|
| Time | O(n log n) | Dominated by sorting; the single pass through sorted cars is O(n) |
| Space | O(n) | The sorted list and stack each hold at most n elements |
"Sorting is O(n log n). The single pass over the sorted array is O(n) — each car is processed once, with one O(1) push or skip. Space is O(n) for the sorted pairs and the stack. There is no way to go below O(n log n) time here unless the positions were already sorted, in which case the pass alone would be O(n)."
Interview Checklist for Car Fleet
- Restate — "count fleets arriving at target; a car that catches the one ahead merges into it"
- State the no-passing rule and explain that blocking only comes from cars ahead
- Explain why simulation is overkill — arrival times are sufficient
- State the arrival time formula:
(target − position) / speed - Explain why you sort by position descending — process closest to target first
- Describe the stack logic: push only if arrival time is strictly greater than the top
- Emphasise strictly greater-than — equal arrival time = merge, not a new fleet
- Return stack length — each element represents one fleet
- Call out: single car, all-same-speed, all-merge, equal arrival times
- State O(n log n) time and O(n) space
Related Problems to Practice
If you can solve Car Fleet cleanly, try these next:
>=, the second car would be pushed as a new fleet even though it catches the first one exactly at the target. Equal arrival time = same fleet. > is the exact right boundary.
