Problem Statement
K Closest Points to Origin
You are given a list of points on a flat map. Each point is written as [x, y], which tells you how far it is sideways (x) and up or down (y). You also get a number k. Your job is to find the k points that sit closest to the center of the map, the spot (0, 0), called the origin. Closeness is measured in a straight line, the way a ruler would measure it.
Signals to notice
Brute force first
Compute all distances, sort, take first k. Full sort is unnecessary for partial selection. That instinct is useful because it follows the prompt literally, but it usually keeps revisiting work the problem is begging you to organize.
The key insight
Max-heap of size k: for each point, compute distance and add to heap. If heap size > k, remove the farthest (heap max). After all points, the heap contains the k closest. Once you hold onto the right piece of information from moment to moment, the problem feels less like trial and error and more like following a shape that was there all along.
Trace it on points=[[3,3],[5,-1],[-2,4]], k=2
start: heap=[] (max-heap keyed by -dist²), k=2 point [3,3]: dist²=18 → push(-18,3,3); heap size 1 ≤ k, keep point [5,-1]: dist²=26 → push(-26,5,-1); heap size 2 ≤ k, keep point [-2,4]: dist²=20 → push(-20,-2,4); heap size 3 > k evict farthest: pop smallest tuple (-26,5,-1) → drops [5,-1] (dist²=26) heap now holds (-20,-2,4) and (-18,3,3) — the 2 closest return [[-2,4],[3,3]]
What must stay true
The max-heap's top is always the farthest of the current k closest. Any point closer than the top displaces it — ensuring the heap always holds the k closest seen so far. When you keep that truth intact, each local choice supports the larger solution instead of fighting it.
Shape of the loop
heap = [] # max-heap via negated dist
for (x, y) in points:
push(heap, (-(x*x + y*y), x, y))
if size(heap) > k: pop(heap) # evict current farthest
return [[x, y] for (_, x, y) in heap]Pseudocode only — the full worked solution lives in the Solution tab.
Easy way to go wrong
Using Euclidean distance with square root — you don't need sqrt for comparison. x² + y² is sufficient and avoids floating-point precision issues. When the code becomes mechanical before the idea is clear, small edge cases start breaking the whole story.