Search lands in PR-5.1 (Pagefind).

How-to Intermediate

Chapter 5 Updated

K Closest Points to Origin

Max-heap of size K on x² + y²; evict the farthest.

  • Full 6m
  • Revision
  • Flow

Problem Statement

Given an array of 2-D points points[i] = [x, y] and integer k, return the k points closest to the origin by Euclidean distance. Any order is acceptable.

Input

An array of integer [x, y] pairs and the count k.

Example input
points = [[1, 3], [-2, 2], [5, 8], [0, 1]]
k      = 2

Output

The k closest points to the origin.

Expected output
[[0, 1], [-2, 2]]
 
// squared distances: 10, 8, 89, 1
// two smallest: 1 and 8

Constraints

  • 1 ≤ k ≤ points.length ≤ 10⁴
  • -10⁴ ≤ x, y ≤ 10⁴

Intuition

Identical structure to “K Closest Elements” — just 2-D Euclidean distance. Never compute the square root: comparisons are preserved by squared distance, and we avoid a floating-point op per element. Use a max-heap of size K keyed on x² + y²; evict the worst when we exceed K.

Walkthrough — points=[[1,3],[-2,2],[5,8],[0,1]], k=2
point      x²+y²   heap (max by dist)                 action
[1,3]       10    [(10, [1,3])]                       push
[-2,2]       8    [(10, [1,3]), (8, [-2,2])]          push (size == k)
[5,8]       89    push → size 3 → pop (89, [5,8])     evict (89 worst)
[0,1]        1    push → size 3 → pop (10, [1,3])     evict (10 worst)
 
heap now holds [(8, [-2,2]), (1, [0,1])] → answer

Solution

k_closest_points.py
import heapq
 
def kClosest(points: list[list[int]], k: int) -> list[list[int]]:
    max_heap: list[tuple[int, list[int]]] = []     # (-distance², point)
    for x, y in points:
        dist_sq = x * x + y * y
        heapq.heappush(max_heap, (-dist_sq, [x, y]))
        if len(max_heap) > k:
            heapq.heappop(max_heap)                # evict the farthest
    return [p for _, p in max_heap]

Complexity

MetricValueReason
TimeO(n log k)Each of n points: one push (log k) plus possibly one pop (log k). Standard bounded-heap cost.
SpaceO(k)Heap capped at K. The returned list is K elements — required output, not auxiliary.

Edge Case Thinking

ScenarioHandling
Duplicate pointsTreated independently; both can be selected if both are within the top K.
Point at originDistance 0 — always survives eviction.
Ties in distanceAny valid selection satisfies “any order” spec. Break ties explicitly if the problem asks.
Very large coordinatesx*x + y*y can overflow 32-bit ints. Python is safe; JS/TS numbers are 64-bit floats — safe up to 2⁵³.
k >= len(points)Return all points unchanged — heap never evicts.

Comments

Comments are disabled in this environment. Set PUBLIC_GISCUS_REPO, PUBLIC_GISCUS_REPO_ID, and PUBLIC_GISCUS_CATEGORY_ID to enable.