#973 K Closest Points to Origin
frequently reported atMetaAmazonSalesforceAppleGoogleLinkedIn
the problem
In plain words
Return the k points closest to (0, 0) by Euclidean distance, in any order.
in points = [[1,3],[-2,2]], k = 1
out [[-2,2]]
Distances² are 10 and 8.
in points = [[3,3],[5,-1],[-2,4]], k = 2
out [[3,3],[-2,4]]
- 1 ≤ k ≤ points.length ≤ 10⁴
- -10⁴ ≤ xᵢ, yᵢ ≤ 10⁴
your turn
Try it before you peek
Read the examples, say the brute force out loud, then write code: here or on LeetCode ↗. Stuck for 20 minutes? Open one hint at a time.
Solve it in the browser
LeetCode-style: complete the class. Compiled by the real javac (Java 17) and judged right here — nothing is sent anywhere.
Solutions are hidden so you can try first. Even 20 minutes of real effort makes the answer stick far better than reading it.
Marking the problem solved, or opening every hint, also shows it.
the aha
Key insight
patternTop-k with a size-k heapQuickselect
Compare squared distances (no sqrt needed). k smallest → max-heap of size k, whose root is the farthest point you're keeping.
solutions
From brute force to optimal
Sort all points by x² + y², take the first k.
- Arrays.sort with comparingInt(dist²).
- Copy the first k.
Full sort.
Sorted copy.
class Solution { public int[][] kClosest(int[][] points, int k) { int[][] copy = points.clone(); Arrays.sort(copy, Comparator.comparingInt(p -> p[0] * p[0] + p[1] * p[1])); return Arrays.copyOf(copy, k); }}Keep the k closest; evict the farthest when the heap exceeds k.
- Max-heap by dist².
- Offer each point; poll when size > k.
- Return the heap's contents.
Heap never exceeds k + 1.
The heap.
class Solution { public int[][] kClosest(int[][] points, int k) { // max-heap by distance²: the root is the farthest of the k kept so far PriorityQueue<int[]> heap = new PriorityQueue<>((a, b) -> Integer.compare(dist(b), dist(a))); for (int[] p : points) { heap.offer(p); if (heap.size() > k) heap.poll(); // evict the farthest } return heap.toArray(new int[0][]); // the k closest, in heap order } private static int dist(int[] p) { return p[0] * p[0] + p[1] * p[1]; // ≤ 2·10^8 for |x|, |y| ≤ 10^4: fits in int }}Dry run on the plane
Partition until the k closest occupy indices 0..k−1.
- Random-pivot partition by dist².
- Recurse into the side containing index k − 1.
Same halving argument as Kth Largest.
O(1) if allowed to reorder the input.
class Solution { private final Random rnd = new Random(1); public int[][] kClosest(int[][] points, int k) { int[][] a = points.clone(); int lo = 0, hi = a.length - 1; while (lo < hi) { // place the k closest in a[0..k-1], any order int p = partition(a, lo, hi); if (p == k - 1) break; if (p < k - 1) lo = p + 1; else hi = p - 1; } return Arrays.copyOf(a, k); } private int partition(int[][] a, int lo, int hi) { // Lomuto with a random pivot swap(a, lo + rnd.nextInt(hi - lo + 1), hi); int pivot = dist(a[hi]), store = lo; for (int i = lo; i < hi; i++) if (dist(a[i]) < pivot) swap(a, i, store++); swap(a, store, hi); return store; } private static int dist(int[] p) { return p[0] * p[0] + p[1] * p[1]; } private static void swap(int[][] a, int i, int j) { int[] t = a[i]; a[i] = a[j]; a[j] = t; }}in the room
How to say it in the interview
talk track
- Clarify: any order is fine, and k ≤ n. Say you'll compare x² + y², so no
sqrtis needed. - Brute: sort all points by distance and take the first k — O(n log n).
- Better: a max-heap of size k. Its root is the farthest point you keep, so a closer point evicts it.
- Complexity: O(n log k) time, O(k) space. Mention quickselect for O(n) average if the interviewer wants faster.
- Test k = n, a point at the origin, and two points at the same distance.
traps
- Using
Math.sqrtand doubles — slower and invites precision issues. Squared ints are exact (max 2·10⁸ fits in int).
what they ask next
Follow-ups
What if the points arrive as a stream?
Keep the same size-k max-heap. Each new point costs O(log k), and the heap always holds the k closest so far.
What if k is close to n?
Quickselect is O(n) on average whatever k is. Or flip the heap: keep the n − k farthest points in a min-heap, and the rest are the answer.
before you submit
Edge cases to test
- k = n: return every point.
- The origin itself has distance 0 and is always kept.
- |x|, |y| ≤ 10⁴ → x² + y² ≤ 2·10⁸, which fits in an int.
practise next
Similar problems
- #215Kth Largest Element in an ArrayMediumin Heaps
- #347Top K Frequent ElementsMediumin Heaps