150NeetCode 150

66.K Closest Points to Origin

MediumHeap / Priority Queue · 3/7

Problem

Given an array points where points[i] = [xi, yi] is a point on the plane and an integer k, return the k points closest to the origin (0, 0).

Distance is Euclidean, sqrt(x² + y²). The answer may be returned in any order and is guaranteed to be unique (apart from order).

Examples

Input:  points = [[1,3],[-2,2]], k = 1
Output: [[-2,2]]
Explanation: dist²(1,3) = 10, dist²(-2,2) = 8. 8 < 10, so [-2,2] is closer.
Input:  points = [[3,3],[5,-1],[-2,4]], k = 2
Output: [[3,3],[-2,4]]
Explanation: squared distances are 18, 26, 20 -> keep 18 and 20.

Constraints

  • 1 <= k <= points.length <= 10^4
  • -10^4 <= xi, yi <= 10^4

💡 Key Insight

Compare squared distances x² + y² — the square root is monotonic, so it never changes the ordering and avoids floating point. We do not need the points fully sorted, only partitioned into "k closest" and "the rest": a size-k max-heap does that in O(n log k), and Quickselect does it in O(n) on average.

Brute Force (Sort by Distance)

TimeO(n log n)SpaceO(log n) to O(n) for the sort, plus O(k) for the output.

Intuition

Sort all points by squared distance and take the first k.

Algorithm

  1. Sort points with comparator x² + y².
  2. Return Arrays.copyOfRange(points, 0, k).

Visualization

points:  [3,3] d=18   [5,-1] d=26   [-2,4] d=20
sorted:  [3,3] 18, [-2,4] 20, [5,-1] 26
k = 2 -> [[3,3],[-2,4]]

Code

java
import java.util.Arrays;

class Solution {
    public int[][] kClosest(int[][] points, int k) {
        // squared distance is enough for ordering
        Arrays.sort(points, (a, b) -> Integer.compare(a[0] * a[0] + a[1] * a[1], b[0] * b[0] + b[1] * b[1]));
        return Arrays.copyOfRange(points, 0, k);
    }
}

Complexity

  • Time: O(n log n) — sorting.
  • Space: O(log n) to O(n) for the sort, plus O(k) for the output.

Complexity Comparison

Approach Time Space
Sort by Distance O(n log n) O(log n)–O(n)
Max-Heap of Size k O(n log k) O(k)
Quickselect O(n) average, O(n²) worst O(1)

Common Pitfalls

  • Using Math.sqrt and doubles — unnecessary and invites precision bugs; compare x² + y² as ints (max 2 · 10^8, fits in int).
  • Using a min-heap capped at k — it would evict the closest points instead of the farthest.
  • Writing the comparator as dist(a) - dist(b) is fine here, but subtraction comparators overflow in general; Integer.compare is safer.
  • In Quickselect, using a fixed pivot (e.g. always hi) degrades to O(n²) on adversarial or sorted input — randomize.