Find the K Closest Points to a Query Location
Company: Uber
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Implement `k_closest_points(points, origin, k)` for two-dimensional integer points.
Return the `k` points closest to the query location `origin`. Rank points by squared Euclidean distance, then by `x`, then by `y`; return the selected points in that order. This tie-breaking rule makes the answer deterministic. `k` will not exceed the number of points.
Avoid square roots. When `k` is much smaller than the number of points, target `O(n log k)` time and `O(k)` auxiliary space.
```hint Keep only the current winners
Maintain a size-`k` max-heap ordered by the same distance and coordinate key used for the final result.
```
```hint Preserve deterministic ties
The heap's notion of the worst retained point must reverse the complete ranking key, not only the distance.
```
### Discussion Extensions
- How could quickselect reduce expected running time when all points are available as one batch?
- For millions of moving points, compare a uniform grid, a quadtree, and a hierarchical spatial cell index.
- If final ranking uses road-network travel distance, where can straight-line distance still provide a safe candidate filter?
Quick Answer: Return the k points closest to a two-dimensional query location with deterministic distance and coordinate tie breaks. Avoid square roots and use a size-k max-heap to achieve O(n log k) time and O(k) space when k is small.
Implement k_closest_points(points, origin, k). Rank two-dimensional integer points by squared Euclidean distance to origin, then by x, then by y. Return the first k points in that exact ranking order. Duplicate points remain separate entries, k may be zero, and square roots are unnecessary.
Constraints
- 0 <= points.length <= 20.
- Every point and origin contains exactly two integer coordinates.
- Each coordinate is between -3,000,000,000 and 3,000,000,000.
- 0 <= k <= points.length.
- Ranking uses exact squared distance, then x, then y; no square root is used.
Examples
Input: ([], [0, 0], 0)
Expected Output: []
Explanation: Selecting zero points from an empty input returns an empty list.
Input: ([[3, 4]], [0, 0], 1)
Expected Output: [[3, 4]]
Explanation: The only point is selected.
Hints
- Use the full key (distance squared, x, y) for both heap retention and final ordering.
- Keep the worst of the current k winners at the heap root so a better incoming point can replace it.
- Widen coordinate differences before squaring so boundary values do not overflow.