The core idea is to avoid recomputing the entire sum from scratch every time getTotalCost() is called. By maintaining a running total that we update on every delivery, the query becomes a simple read of a primitive variable. We also need to store each driver’s hourly rate and their personal cumulative cost so that new deliveries can be priced correctly and individual records remain accurate.
The system uses two dictionaries (hash maps). The first, rateMap, maps a driver's ID to their hourly pay rate. The second, driverTotal, maps a driver's ID to the total earnings they have accumulated so far. A separate double variable, grandTotal, holds the sum of all drivers' earnings across all deliveries. When addDriver is called, we insert the driver into both maps, initializing their accumulated cost to zero. When recordDelivery is called, we compute the elapsed time in seconds, convert it to hours by dividing by 3600, and multiply by the driver’s rate to get the delivery cost. We then add this cost to the driver's personal total in driverTotal and to the global grandTotal. The getTotalCost method simply returns grandTotal.
Walk through the provided example:
addDriver(1, 20.0) → rateMap gets {1: 20.0}, driverTotal gets {1: 0.0}, grandTotal = 0.0.getTotalCost() → returns 0.0.recordDelivery(1, 1000000000, 1000003600) → duration is 3600 seconds = 1.0 hour. Cost = 1.0 * 20.0 = 20.0. driverTotal[1] becomes 20.0, grandTotal becomes 20.0.getTotalCost() → returns 20.0.addDriver(2, 30.0) → rateMap now {1: 20.0, 2: 30.0}, driverTotal now {1: 20.0, 2: 0.0}.recordDelivery(2, 1000003600, 1000005400) → duration is 1800 seconds = 0.5 hours. Cost = 0.5 * 30.0 = 15.0. driverTotal[2] becomes 15.0, grandTotal becomes 35.0.getTotalCost() → returns 35.0.recordDelivery(1, 1000005400, 1000009000) → duration 3600 seconds = 1.0 hour. Cost = 20.0. driverTotal[1] becomes 40.0, grandTotal becomes 55.0.getTotalCost() → returns 55.0.addDriver(3, 25.0) → maps updated accordingly.recordDelivery(3, 1000009000, 1000012600) → duration 3600 seconds = 1.0 hour. Cost = 25.0. driverTotal[3] becomes 25.0, grandTotal becomes 80.0.getTotalCost() → returns 80.0.class DeliveryCost: def __init__(self): self.hourly_rates = {} self.driver_earnings = {} self.running_total = 0.0 def addDriver(self, driverId: int, usdHourlyRate: float) -> None: self.hourly_rates[driverId] = usdHourlyRate self.driver_earnings[driverId] = 0.0 def recordDelivery(self, driverId: int, startTime: int, endTime: int) -> None: rate = self.hourly_rates[driverId] # Convert seconds to fractional hours hours_worked = (endTime - startTime) / 3600.0 delivery_pay = hours_worked * rate previous_total = self.driver_earnings[driverId] self.driver_earnings[driverId] = previous_total + delivery_pay self.running_total += delivery_pay def getTotalCost(self) -> float: return self.running_totalimport java.util.HashMap;import java.util.Map;class DeliveryCost { private Map<Integer, Double> hourlyRates; private Map<Integer, Double> accumulatedCosts; private double runningTotal; public DeliveryCost() { hourlyRates = new HashMap<>(); accumulatedCosts = new HashMap<>(); runningTotal = 0.0; } public void addDriver(int driverId, double usdHourlyRate) { hourlyRates.put(driverId, usdHourlyRate); accumulatedCosts.put(driverId, 0.0); } public void recordDelivery(int driverId, int startTime, int endTime) { double rate = hourlyRates.get(driverId); // Convert seconds to fractional hours double hoursWorked = (endTime - startTime) / 3600.0; double deliveryPay = hoursWorked * rate; double previousTotal = accumulatedCosts.get(driverId); accumulatedCosts.put(driverId, previousTotal + deliveryPay); runningTotal += deliveryPay; } public double getTotalCost() { return runningTotal; }}addDriver, recordDelivery, getTotalCost) performs a constant number of hash map operations and arithmetic calculations.