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: sqrt((x1 - x2)² + (y1 - y2)²).
You may return the answer in any order.
Input: points = [[1,3],[-2,2]], k = 1
Output: [[-2,2]]
Explanation:
Distance from [1,3] to origin = sqrt(1² + 3²) = sqrt(10) ≈ 3.16
Distance from [-2,2] to origin = sqrt(4 + 4) = sqrt(8) ≈ 2.83
Closest point is [-2,2]
Input: points = [[3,3],[5,-1],[-2,4]], k = 2
Output: [[3,3],[-2,4]]
Distances: [18, 26, 20]
Two closest are [3,3] and [-2,4]
We need the k smallest distances, which suggests:
Optimization: We don't need exact distances, just relative ordering. Use squared distance to avoid expensive sqrt().
Distance² = x² + y²
This is a Max-Heap Top-K problem:
Time: O(n log k) - better than sorting all points O(n log n)
Can achieve O(n) average, but more complex implementation.
Sort all points by distance, take first k: O(n log n)
Time: O(n log k)
Space: O(k)
1import java.util.PriorityQueue;
2
3class Solution {
4 public int[][] kClosest(int[][] points, int k) {
5 // Max-heap storing points by distance (farthest at top)
6 PriorityQueue<int[]> maxHeap = new PriorityQueue<>(
7 (a, b) -> (b[0] * b[0] + b[1] * b[1]) - (a[0] * a[0] + a[1] * a[1])
8 );
9
10 for (int[] point : points) {
11 if (maxHeap.size() < k) {
12 // Heap not full, add point
13 maxHeap.offer(point);
14 } else {
15 int[] farthest = maxHeap.peek();
16 int dist = point[0] * point[0] + point[1] * point[1];
17 int farthestDist = farthest[0] * farthest[0] + farthest[1] * farthest[1];
18
19 if (dist < farthestDist) {
20 // Point is closer than farthest in heap
21 maxHeap.poll();
22 maxHeap.offer(point);
23 }
24 }
25 }
26
27 // Convert heap to array
28 int[][] result = new int[k][2];
29 for (int i = 0; i < k; i++) {
30 result[i] = maxHeap.poll();
31 }
32
33 return result;
34 }
35}
36