2Brute2Best
🔥0

K Closest Points to Origin

Medium·LeetCode #973Basic Anchor
LeetCode
30-Second Mental ModelHeap — Top K (Closest / distance): max-heap of size K on the squared distance
Complexity:O(N log N)→O(N log K)
Key Insight

Keep a max-heap of at most K points, keyed on x² + y². Push each point. When the heap holds K + 1 points, pop the top: the top is the farthest point, so it is the one to evict. When all points are read, the heap holds the K closest.

Core Validity Invariant

After reading any number of points, the heap holds the K closest of the points read so far. Push the new point, then pop the farthest one if there are now K + 1.

01

Problem

You get a list of points on a flat grid. Point i is points[i] = [xi, yi]. Its distance to the origin (0, 0) is the straight-line distance, √(xi² + yi²).

Return the k points closest to the origin. You may return them in any order. The answer is unique apart from that order.

Input

points, a list of [x, y] pairs, and an integer k.

Output

A list of k points: the ones with the smallest distance to the origin.

Example 1
Input: points = [[1, 3], [-2, 2]], k = 1
Output: [[-2, 2]]

The distance of (1, 3) is √10 and the distance of (−2, 2) is √8. Since √8 < √10, the point (−2, 2) is closer, and we keep only one point.

Example 2
Input: points = [[3, 3], [5, -1], [-2, 4]], k = 2
Output: [[3, 3], [-2, 4]] (any order)

The distances are √18, √26 and √20. The two smallest are √18 and √20, so the answer is (3, 3) and (−2, 4).

Constraints
  • • 1 ≤ k ≤ points.length ≤ 10^4
  • • −10^4 ≤ xi, yi ≤ 10^4
02

First, think yourself

Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.

  1. 1.

    The distance has a square root in it. Do I need the square root to decide which of two points is closer?

  2. 2.

    I only need k points. If a new point is closer than one I already kept, which kept point should leave?

  3. 3.

    Sorting all the points works. What work is wasted when I only need the first k of the sorted list?

  4. 4.

    A heap gives me one item quickly. Should it be the smallest item or the largest, if I want to throw out the farthest point?

  5. 5.

    Does the answer have to come out in any particular order?

03

Brute force approach

05

Optimized approach

06

Why does this algorithm work?

07

Dry run

08

All approaches compared

ApproachIdeaTimeSpace
Brute ForceSort all points by squared distance and keep the first kO(N log N)O(K)
OptimalKeep the K closest points in a max-heap; pop the farthest when the heap grows past KO(N log K)O(K)
09

Why does this belong to this pattern?

Clues in the problem statement
  • “k closest to the origin”We keep only K items with the smallest score, not all of them. That is Top K, so a heap of size K.
  • “distance from the origin”The score is x² + y². Squares keep the same order, so the square root is not needed.
  • “in any order”The answer does not need sorting, so the heap can be read out directly.
Score each point: x² + y²+keep the K smallest scores+max-heap of size K→Heap — Top K (Closest / distance): max-heap of size K on the squared distance

This is the anchor of the Closest sub-pattern. We keep the K smallest scores, so the item to throw out is the largest one, and the heap must be a max-heap. Kth Largest Element is the opposite rule: keep the K largest in a min-heap, because the item to throw out is the smallest. Next in this sub-pattern is Find K Closest Elements. Its input is sorted, so the answer is a window and binary search beats the heap there.

10

Don't make this mistake

Min-heap of size K (pattern confusion)
✗ priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> heap;
✓ priority_queue<pair<int, int>> heap;

A min-heap pops the SMALLEST key first, and the smallest key is the closest point, so it gets thrown out. Dry run: points = [[1, 3], [−2, 2], [5, 8], [0, 1], [−3, 4], [2, −1]] with k = 3. The min-heap throws out (0, 1), then (−2, 2), then (2, −1), which are the three closest points. It keeps (1, 3), (−3, 4) and (5, 8), which are the farthest. The max-heap keeps the right three: (−2, 2), (0, 1) and (2, −1).

Returning scores or indexes instead of points
✗ result.push_back({heap.top().first});
✓ result.push_back(points[heap.top().second]);

The answer is a list of [x, y] points. The heap holds (score, index) pairs, so read the point back from points[index]. A score such as 8 does not say which point it came from.

Pushing all n points, then popping n − K
✗ for (auto& p : points) heap.push(...); while ((int)heap.size() > k) heap.pop();
✓ for (int i = 0; i < n; i++) { heap.push(...); if ((int)heap.size() > k) heap.pop(); }

The answer is the same, but the heap now holds all n points at once. That costs O(N log N) instead of O(N log K), and O(N) memory instead of O(K). Pop as you go, so the heap never grows past K + 1.

11

Want to implement this?

Write it yourself on LeetCode, then come back and compare your code with the solutions above.

Open coding workspace
How did it go?
Beyond The LeetCode Problem

How this concept connects to System Design & C++ Systems

Bridge DSA with production engineering

Top engineering interviews test whether you understand how algorithms like Heap — Top K translate into production architectures and low-level memory mechanics.