Compute nearest courier for each customer
Company: DoorDash
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: Onsite
Quick Answer: This interview question evaluates algorithm design, data structures, correctness, complexity, edge cases, and implementation details in a realistic interview setting. A strong answer for Compute nearest courier for each customer states assumptions, handles edge cases, explains trade-offs, and shows how to validate the result clearly.
Constraints
- 0 <= number of customers, couriers <= 1e5
- Courier ids are integers; ids may repeat across distinct locations in adversarial inputs but tie-breaking still selects the smallest id at minimum distance
- Coordinates fit in 32-bit signed integers; squared distances fit in 64-bit
- Compare squared distances (no sqrt) for exactness with integer inputs
- If couriers is empty, every customer maps to -1
Examples
Input: ([[0, 0], [5, 5]], [[1, 1, 10], [4, 4, 20], [10, 10, 30]])
Expected Output: [10, 20]
Explanation: Customer (0,0) is closest to courier 10 at (1,1) (d^2=2). Customer (5,5) is closest to courier 20 at (4,4) (d^2=2).
Input: ([[2, 2]], [[0, 0, 7], [4, 4, 3]])
Expected Output: [3]
Explanation: Both couriers are at squared distance 8 from (2,2); the tie is broken by the smaller id, so courier 3 wins.
Input: ([[0, 0]], [])
Expected Output: [-1]
Explanation: No couriers exist, so the customer maps to the -1 sentinel.
Input: ([[3, 0]], [[0, 0, 1], [6, 0, 2]])
Expected Output: [1]
Explanation: Both couriers are 3 units away (d^2=9), so the smaller id (1) is returned.
Input: ([], [[0, 0, 1]])
Expected Output: []
Explanation: There are no customers, so the result is empty regardless of couriers.
Input: ([[0, 0], [0, 0]], [[1, 0, 5], [-1, 0, 5], [0, 1, 9]])
Expected Output: [5, 5]
Explanation: All three couriers are at squared distance 1 from (0,0); the smallest id at minimum distance is 5, returned for both identical customers.
Input: ([[-3, -4]], [[0, 0, 100], [-3, 0, 50]])
Expected Output: [50]
Explanation: Courier 100 is at d^2=25, courier 50 at d^2=16; courier 50 is strictly closer.
Hints
- Start with the brute force: for each customer scan all couriers and keep the running minimum, comparing the pair (squared_distance, id) lexicographically so ties go to the smallest id.
- Use squared distance (cx-ax)^2 + (cy-ay)^2 instead of the actual distance — it preserves ordering, avoids sqrt, and stays exact for integer coordinates.
- To beat O(n*m) for large inputs, build a spatial index over the couriers once (uniform grid / spatial hash, or a k-d tree) and query it per customer; expand grid rings outward and stop once the next ring cannot beat your best candidate.
- Edge cases: no couriers -> -1; duplicate courier locations -> the id tie-break makes the result deterministic; for real lat/lng use haversine, not planar Euclidean.