Compute max simultaneous drivers last 24 hours
Company: Rippling
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: Technical Screen
Quick Answer: This question evaluates proficiency in reasoning about time-interval overlap, event aggregation, and online data structures for streaming interval queries, testing skills in algorithm design and temporal data handling within the Coding & Algorithms domain.
Constraints
- 0 <= len(deliveries) <= 200000
- -10^9 <= startTime < endTime <= now <= 10^9
- driverId is an integer
- All times are integer minutes; 24 hours = 1440 minutes
- Delivery records may be unsorted and may contain duplicate or overlapping intervals for the same driver
Examples
Input: ([], 1000)
Expected Output: 0
Explanation: There are no delivery records, so no driver can be active.
Input: ([(1, 0, 60), (2, 30, 90), (3, 45, 50)], 100)
Expected Output: 3
Explanation: All three distinct drivers are active during the interval [45, 50), so the maximum is 3.
Input: ([(1, 0, 100), (1, 50, 150), (2, 75, 125), (3, 130, 160)], 200)
Expected Output: 2
Explanation: Driver 1's overlapping records merge into one active span [0, 150). The maximum distinct active drivers is 2, for example drivers 1 and 2 during [75, 125).
Input: ([(1, 10, 20), (1, 10, 20), (2, 15, 18)], 30)
Expected Output: 2
Explanation: The duplicate records for driver 1 still count as only one active driver. During [15, 18), drivers 1 and 2 are active.
Input: ([(1, 100, 560), (2, 560, 600), (3, 550, 570), (4, 600, 700), (5, 1990, 2000)], 2000)
Expected Output: 2
Explanation: The window is (560, 2000]. Driver 1's delivery ends exactly at the open left boundary and is ignored. Drivers 2 and 3 overlap just after 560, giving a maximum of 2.
Input: ([(1, 0, 10), (2, 10, 20), (3, 20, 30)], 30)
Expected Output: 1
Explanation: Because delivery intervals are half-open, [0, 10) and [10, 20) do not overlap at time 10. The maximum is 1.
Solution
def solution(deliveries, now):
window = 24 * 60
left = now - window
intervals_by_driver = {}
for driver_id, start, end in deliveries:
# Delivery intervals are [start, end). The query window is (left, now].
# With completed deliveries, an interval contributes iff end > left and start < now.
if end <= left or start >= now:
continue
clipped_start = max(start, left)
clipped_end = min(end, now)
if clipped_start < clipped_end:
intervals_by_driver.setdefault(driver_id, []).append((clipped_start, clipped_end))
events = []
# Merge intervals per driver so each driver contributes at most 1 to any instant.
for intervals in intervals_by_driver.values():
intervals.sort()
cur_start, cur_end = intervals[0]
for start, end in intervals[1:]:
# Touching intervals can be merged: [a, b) and [b, c) keep the driver continuously counted as 1.
if start <= cur_end:
if end > cur_end:
cur_end = end
else:
events.append((cur_start, 1))
events.append((cur_end, -1))
cur_start, cur_end = start, end
events.append((cur_start, 1))
events.append((cur_end, -1))
events.sort()
current = 0
best = 0
i = 0
while i < len(events):
time = events[i][0]
delta = 0
while i < len(events) and events[i][0] == time:
delta += events[i][1]
i += 1
current += delta
if current > best:
best = current
return bestTime complexity: O(n log n), where n is the number of delivery records. Intervals are sorted per driver and sweep events are sorted globally.. Space complexity: O(n).
Hints
- A same driver can have overlapping records, but must only be counted once. Consider clipping records to the 24-hour window, then merging intervals per driver first.
- After each driver's intervals are disjoint, use a sweep line: interval starts add 1 and interval ends subtract 1. Group events with the same timestamp to respect half-open interval semantics.