Courier Delivery Cost Tracker
Company: Rippling
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates a candidate's ability to design a stateful, multi-part class that combines interval tracking with incremental balance accounting, a common pattern in coding interviews for backend systems roles. It tests practical application skills across data structure design, running-total bookkeeping, and computing maximum overlap within a time window, moving from straightforward bookkeeping to a harder interval-scheduling extension.
Constraints
- At most 10^5 total operations.
- 1 <= driverId <= 10^9.
- 0 <= startTime < endTime <= 10^9 and 0 <= windowStart < windowEnd <= 10^9.
- 0 <= cost, amount <= 10^6.
- Every driverId passed to recordDelivery/getTotalCost/payUpTo/getTotalCostUnpaid was registered via addDriver first.
- A single driver never has two overlapping deliveries.
Examples
Input: (['addDriver', 'addDriver', 'recordDelivery', 'recordDelivery', 'recordDelivery', 'getTotalCost', 'getTotalCost', 'payUpTo', 'getTotalCostUnpaid', 'payUpTo', 'getTotalCostUnpaid', 'maxConcurrentDrivers'], [[1], [2], [1, 0, 100, 50], [1, 100, 200, 30], [2, 50, 150, 40], [1], [2], [1, 60], [1], [1, 100], [1], [0, 300]])
Expected Output: [None, None, None, None, None, 80, 40, 60, 20, 20, 0, [2, 50, 150]]
Explanation: Mirrors the prompt example: costs 80/40, incremental payouts of 60 then 20 drive the unpaid balance to 0, and peak concurrency of 2 is sustained continuously across [50,150) even though driver 1 swaps deliveries at t=100.
Input: (['addDriver', 'getTotalCost', 'getTotalCostUnpaid', 'payUpTo', 'getTotalCostUnpaid', 'maxConcurrentDrivers'], [[5], [5], [5], [5, 100], [5], [0, 100]])
Expected Output: [None, 0, 0, 0, 0, [0, -1, -1]]
Explanation: A registered driver with zero deliveries owes nothing, so getTotalCost/Unpaid are 0 and payUpTo pays 0. With no deliveries recorded, the window has no coverage: [0,-1,-1].
Input: (['addDriver', 'recordDelivery', 'maxConcurrentDrivers', 'maxConcurrentDrivers', 'maxConcurrentDrivers'], [[1], [1, 10, 50, 7], [30, 40], [60, 70], [0, 20]])
Expected Output: [None, None, [1, 30, 40], [0, -1, -1], [1, 10, 20]]
Explanation: One delivery on [10,50). Window [30,40) clips it to [30,40); window [60,70) does not overlap so returns [0,-1,-1]; window [0,20) clips to [10,20).
Input: (['addDriver', 'addDriver', 'addDriver', 'recordDelivery', 'recordDelivery', 'recordDelivery', 'recordDelivery', 'maxConcurrentDrivers', 'getTotalCost'], [[1], [2], [3], [1, 0, 10, 5], [2, 0, 10, 5], [1, 20, 30, 5], [3, 20, 30, 5], [0, 30], [1]])
Expected Output: [None, None, None, None, None, None, None, [2, 0, 10], 10]
Explanation: Concurrency reaches 2 on both [0,10) and [20,30) with a lull between; the tie is broken by the smallest peakStart, so [2,0,10]. Driver 1's two deliveries total 10.
Input: (['addDriver', 'addDriver', 'addDriver', 'recordDelivery', 'recordDelivery', 'recordDelivery', 'recordDelivery', 'maxConcurrentDrivers', 'getTotalCost', 'getTotalCostUnpaid', 'payUpTo', 'getTotalCostUnpaid'], [[1], [2], [3], [1, 0, 100, 50], [1, 100, 200, 30], [2, 50, 150, 40], [3, 60, 140, 20], [0, 300], [1], [1], [1, 1000], [1]])
Expected Output: [None, None, None, None, None, None, None, [3, 60, 140], 80, 80, 80, 0]
Explanation: Three drivers overlap on [60,140) for a peak of 3, held continuously through driver 1's delivery swap at t=100. payUpTo(1,1000) is capped at the 80 owed and returns 80, zeroing the unpaid balance.
Hints
- Parts 1 and 2 are pure bookkeeping: keep a per-driver running total and a per-driver paid amount. Unpaid balance is just total - paid, and payUpTo pays min(amount, unpaid).
- Persist every delivery's (startTime, endTime) even though getTotalCost ignores them — Part 3 needs the full set across all drivers.
- For Part 3, use a sweep line: clip each delivery to the window, add +1 at the clipped start and -1 at the clipped end of a boundary map, then sweep the sorted coordinates accumulating the running count.
- Because the intervals are half-open, +1 at a start and -1 at an end that fall on the same coordinate cancel, so a driver swapping deliveries at the same instant does not drop the count.
- Find the max running count, then return the FIRST maximal run of contiguous coordinate-intervals whose count equals the max — that gives the smallest peakStart and the continuous [peakStart, peakEnd). Return [0, -1, -1] when no delivery overlaps the window.