Streaming Points: Remove Any Pair Within a Distance
Company: Google
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This question evaluates practical use of ordered data structures for streaming input with proximity-based removal logic. It tests balanced BST or sorted-set operations, floating-point comparison handling, and greedy pair selection — skills commonly assessed in algorithm-focused software engineering interviews.
Constraints
- 1 <= len(stream) <= 10^5
- 0 <= d <= 10^9
- Each stream value is a double (positions may repeat; equal positions are distinct points).
- Use an ordered structure (TreeSet / TreeMap / balanced BST / sorted container / min-heap) so closest neighbors are found without rescanning all points.
- Tolerate floating-point error: treat b - a <= d + eps (eps = 1e-9) as within d.
Examples
Input: ([1.0, 5.0, 1.4, 4.9], 0.5)
Expected Output: [[1.0, 1.4], [4.9, 5.0]]
Explanation: Worked example: 1.4 pairs with 1.0 (gap 0.4); later 4.9 pairs with 5.0 (gap 0.1).
Input: ([], 0.5)
Expected Output: []
Explanation: Empty stream — nothing to insert or emit.
Input: ([3.0], 1.0)
Expected Output: []
Explanation: A single point can never form a pair.
Input: ([2.0, 2.0], 0.0)
Expected Output: [[2.0, 2.0]]
Explanation: Equal positions are distinct points; gap 0 <= d=0, so they pair and are emitted.
Input: ([0.0, 10.0, 20.0], 0.5)
Expected Output: []
Explanation: No two held points are ever within 0.5.
Input: ([1.0, 2.0, 3.0, 4.0], 1.0)
Expected Output: [[1.0, 2.0], [3.0, 4.0]]
Explanation: 2.0 pairs with 1.0 (gap 1.0); 4.0 pairs with 3.0 (gap 1.0). 3.0 is alone when inserted (1.0,2.0 already gone).
Input: ([5.0, 1.0, 1.5, 5.4], 0.5)
Expected Output: [[1.0, 1.5], [5.0, 5.4]]
Explanation: Smallest-first: 1.5 pairs with 1.0 before any 5.x pair; then 5.4 pairs with 5.0.
Input: ([1.0, 1.1, 1.2], 0.15)
Expected Output: [[1.0, 1.1]]
Explanation: 1.1 pairs with 1.0 (gap 0.1). When 1.2 arrives it is alone, so no further pair.
Input: ([-3.0, -2.5, -2.4], 0.6)
Expected Output: [[-3.0, -2.5]]
Explanation: Negatives: -2.5 pairs with -3.0 (gap 0.5). -2.4 is then alone.
Input: ([0.0, 0.0, 0.0, 0.0], 0.0)
Expected Output: [[0.0, 0.0], [0.0, 0.0]]
Explanation: Four identical points form two pairs as duplicates are inserted; each pair has gap 0 <= d=0.
Hints
- Keep the held points in a sorted/ordered structure. The pair with the smallest positions is always the two smallest currently-held points, so you only ever need to look at the front of the order.
- After each insertion, loop: while at least two points remain and (second_smallest - smallest) <= d + eps, emit and remove both, then re-check the new two smallest.
- A newly inserted point can trigger a chain of removals, but each point is removed at most once overall, so the total work across the whole stream is bounded.
- For floating-point safety, compare with an epsilon (b - a <= d + 1e-9) and remember that two equal positions still count as two distinct points.