43. K Closest Points to Origin
Return the k points closest to the origin (0, 0) by Euclidean distance, in any order. The answer is unique.
Example 1
Input:
points = [[1,3],[-2,2]], k = 1Output:
[[-2,2]]Example 2
Input:
points = [[3,3],[5,-1],[-2,4]], k = 2Output:
[[3,3],[-2,4]]Hint 1
Compare squared distances: no square roots needed.
Hint 2
Keep a max-heap of size k and evict the farthest point.
Approach 1: Sort by distance
Sort all points and take k.
⏱ Time O(n log n)💾 Space O(n)
Approach 2: Max-heap of size k ✅
Evict the farthest whenever size exceeds k.
⏱ Time O(n log k)💾 Space O(k)
Reference solution for Max-heap of size k (time O(n log k), space O(k)). Each solution passes every test in all four languages.
class Solution:
def kClosest(self, points: List[List[int]], k: int) -> List[List[int]]:
heap = [] # max-heap (negated) of the k closest
for x, y in points:
heapq.heappush(heap, (-(x * x + y * y), x, y))
if len(heap) > k:
heapq.heappop(heap) # drop the farthest
return [[x, y] for _, x, y in heap]class Solution {
public int[][] kClosest(int[][] points, int k) {
PriorityQueue<int[]> heap = new PriorityQueue<>((a, b) -> (b[0] * b[0] + b[1] * b[1]) - (a[0] * a[0] + a[1] * a[1]));
for (int[] p : points) {
heap.offer(p);
if (heap.size() > k) heap.poll(); // drop the farthest
}
return heap.toArray(new int[0][]);
}
}class Solution {
public:
vector<vector<int>> kClosest(vector<vector<int>>& points, int k) {
priority_queue<pair<int, int>> heap; // (distance², index), max-heap
for (int i = 0; i < (int)points.size(); i++) {
heap.push({points[i][0] * points[i][0] + points[i][1] * points[i][1], i});
if ((int)heap.size() > k) heap.pop(); // drop the farthest
}
vector<vector<int>> res;
while (!heap.empty()) { res.push_back(points[heap.top().second]); heap.pop(); }
return res;
}
};class MinHeap {
constructor(less = (a, b) => a < b) { this.a = []; this.less = less; }
get size() { return this.a.length; }
peek() { return this.a[0]; }
push(x) { const a = this.a; a.push(x); let i = a.length - 1;
while (i > 0) { const p = (i - 1) >> 1; if (!this.less(a[i], a[p])) break; [a[i], a[p]] = [a[p], a[i]]; i = p; } }
pop() { const a = this.a, top = a[0], last = a.pop();
if (a.length) { a[0] = last; let i = 0;
while (true) { const l = 2 * i + 1, r = l + 1; let m = i;
if (l < a.length && this.less(a[l], a[m])) m = l;
if (r < a.length && this.less(a[r], a[m])) m = r;
if (m === i) break; [a[i], a[m]] = [a[m], a[i]]; i = m; } }
return top; }
}
function kClosest(points, k) {
const d = p => p[0] * p[0] + p[1] * p[1];
const heap = new MinHeap((a, b) => d(a) > d(b)); // max-heap by distance
for (const p of points) {
heap.push(p);
if (heap.size > k) heap.pop(); // drop the farthest
}
return heap.a;
}Try solving it yourself first. Interviewers care more about how you explain the approach than about the finished code.
Watch the core idea of this problem step by step. Change the input and press Visualize.
Explained in the lesson Heaps & Priority Queues.
Run your code to see results here.