We have a list of 2D points and need to find the k points closest to the origin (0, 0). The Euclidean distance from a point (x, y) to the origin is sqrt(x^2 + y^2). We only care about the relative ordering of distances, not the actual values, so we can compare x^2 + y^2 directly and skip the square root. The square root function is monotonically increasing, so sqrt(a) < sqrt(b) exactly when a < b, which means ordering by squared distance gives the same result as ordering by true distance.
The answer can be returned in any order. We do not need a fully sorted result, only any k elements that are the smallest. That allows approaches faster than a full sort.
-10^4 <= xi, yi <= 10^4 -> The largest squared distance is 10^4^2 + 10^4^2 = 2 10^8, which fits in a signed 32-bit integer (max ~2.1 10^9). Distances never overflow int, so there is no need for long.1 <= k <= points.length <= 10^4 -> k is always a valid count, so no bounds checking is needed. With n up to 10,000, an O(n log n) sort runs fine, but the "any order" allowance leaves room for O(n log k) and average O(n) solutions.Compute the squared distance for every point, sort the entire array by that distance, and take the first k elements. Sorting produces a fully ordered array, which is more than the problem asks for. We only need the k smallest, not all n in order, but sorting gets us there with no extra logic.
points array using a custom comparator that compares x^2 + y^2 for each point.k elements of the sorted array.Sorting touches all n points even though we only need the k smallest. The next approach keeps only the k closest points seen so far, lowering the cost when k is much smaller than n.
Instead of sorting the entire array, maintain a max-heap of size k. The heap holds the k closest points seen so far, with the farthest of those k at the top.
Scanning through the points, compare each new point's distance against the heap's maximum. If the new point is closer, remove the farthest point and insert the new one. If the heap has fewer than k elements, add the point directly. The farthest-on-top ordering makes the comparison against the current worst candidate an O(1) lookup.
The invariant is that after processing the first i points, the heap holds the k closest among those i (or all of them if i < k). When point i+1 arrives, either it is closer than the current farthest, in which case it belongs in the top k and the farthest is evicted, or it is not closer, in which case it cannot displace any of the current k. Removing the farthest is safe: a point removed because k other points are closer can never re-enter, since later points only shrink the set of distances that beat it.
The heap wins when k is small, but every element still costs O(log k). The next approach drops the per-element log factor by partitioning the array around the k-th smallest distance, reaching O(n) on average.
The task reduces to finding the k smallest distances and returning those points, in any order. Quickselect does this without fully sorting: it rearranges the array so that the element at index k sits in its final sorted position, with every smaller element to its left and every larger element to its right. Once index k is settled, the first k slots hold the answer regardless of their internal order.
Quickselect chooses a pivot, partitions the array around it (smaller distances go left, larger go right), and checks where the pivot landed. If the pivot is at index k, the first k elements are the answer. If it landed past k, recurse on the left part. If before k, recurse on the right part.
The savings come from recursing on only one side. Quicksort recurses on both halves for O(n log n) total work. Quickselect descends into one half, roughly halving the remaining work each step: n + n/2 + n/4 + ... = 2n = O(n) on average.
quickSelect(points, left, right, k).left and right.