K Closest Points to Origin
Problem
https://leetcode.com/problems/k-closest-points-to-origin/
Given an array of points where points[i] = [xi,
yi] represents a point on the X-Y plane and an
integer k, return the k closest points to the origin
(0, 0).
The distance between two points on the X-Y plane is the Euclidean
distance (i.e., sqrt(x1- x2)2+ (y1- y2)2).
You may return the answer in any order. The answer is guaranteed to be unique (except for the order that it is in).
Example 1:
Input: points = [[1,3],[-2,2]], k = 1
Output: [[-2,2]]
Explanation:
The distance between (1, 3) and the origin is sqrt(10).
The distance between (-2, 2) and the origin is sqrt(8).
Since sqrt(8) < sqrt(10), (-2, 2) is closer to the origin.
We only want the closest k = 1 points from the origin, so the answer is just [[-2,2]].
Example 2:
Input: points = [[3,3],[5,-1],[-2,4]], k = 2
Output: [[3,3],[-2,4]]
Explanation: The answer [[-2,4],[3,3]] would also be accepted.
Constraints:
1 <= k <= points.length <= 104-104<= xi, yi<= 104
Pattern
Heap, Sorting
Approaches
Explanation
The \(k`th closest point is the largest element among the :math:`k\) largest elements. So if we maintain a max-heap containing only the \(k\) closest points seen so far, we only need to look at the top of the heap to determine whether a new point should be in our \(k\) closest.
Go through points and push \((x^2 + y^2, x, y)\) onto the heap until
it holds \(k\) points. After that, each new point only matters if it is
closer than the top point (the furthest of the current \(k\) closest
points). In that case, the top point can no longer be one of the \(k\)
closest, so we replace it.
Once all numbers are processed, the heap holds the \(k\) closest points.
Code
import heapq
def kClosest(points: list[list[int]], k: int) -> list[list[int]]:
"""Return the k closest points to the origin."""
heap = []
for [x, y] in points:
d = x**2 + y**2
if len(heap) < k:
heapq.heappush_max(heap, (d, x, y))
elif d < heap[0][0]:
heapq.heapreplace_max(heap, (d, x, y))
return [[x, y] for _, x, y in heap]
Test
>>> from k_closest_points_to_origin__max_heap import kClosest
>>> kClosest([[1, 3], [-2, 2]], 1)
[[-2, 2]]
>>> sorted(kClosest([[3, 3], [5, -1], [-2, 4]], 2))
[[-2, 4], [3, 3]]
Complexity
\(n\) is the number of elements in nums
Measure |
Complexity |
Notes |
|---|---|---|
Time |
\(O(n \log k)\) |
one pass through the array, pushing elements onto the heap is \(O(\log k)\) |
Auxiliary Space |
\(O(k)\) |
max heap |
- k_closest_points_to_origin__max_heap.kClosest(points: list[list[int]], k: int) list[list[int]]
Return the k closest points to the origin.