# K Closest Points to the Origin

`Heap`

Easy

We have a list of`points` on the plane. Find the`K`closest points to the origin`(0, 0)`.

(Here, the distance between two points on a plane is the Euclidean distance.)

You may return the answer in any order. The answer is guaranteed to be unique (except for the order that it is in.)

Example 1:

``````Input: points = [[1,3],[-2,2]], K = 1
Output: [[-2,2]]
Explanation:

The distance between (1, 3) and the origin is sqrt(10).
The distance between (-2, 2) and the origin is sqrt(8).
Since sqrt(8) < sqrt(10), (-2, 2) is closer to the origin.
We only want the closest K = 1 points from the origin, so the answer is just [[-2,2]].
``````

Example 2:

``````Input: points = [[3,3],[5,-1],[-2,4]], K = 2
Output: [[3,3],[-2,4]]

(The answer [[-2,4],[3,3]] would also be accepted.)
``````

Note:

1. `1 <= K <= points.length <= 10000`
2. `-10000 < points[i][0] < 10000`
3. `-10000 < points[i][1] < 10000`

## Solution

#### Use Max-Heap

Space: O(k) - max heap of size k

Time: O(n logk + k)

``````import java.util.*;
public class Main {
public static List<List<Integer>> topK(List<List<Integer>> input, int n, int k){
PriorityQueue<List<Integer>> maxHeap = new PriorityQueue<List<Integer>>(k, new Comparator<List<Integer>>() {
public int compare(List<Integer> a, List<Integer> b) {
return b.get(0)*b.get(0) + b.get(1) * b.get(1) - a.get(0) * a.get(0) - a.get(1) * a.get(1);
}
});

for (List<Integer> c: input) {
maxHeap.offer(c);
if (!maxHeap.isEmpty() && maxHeap.size() > k) {
maxHeap.poll();
}
}
while (!maxHeap.isEmpty()) {
}
return ans;
}

public static void main (String[] args){
List<List<Integer>> input = new ArrayList<>();
int n = 6;
int k = 2;
System.out.println(topK(input,n,k));
}

}
``````

Another Max-Heap (with lambda function)

``````class Solution {
public int[][] kClosest(int[][] points, int K) {
PriorityQueue<int[]> pq = new PriorityQueue<int[]>(
(p1, p2) -> p2[0] * p2[0] + p2[1] * p2[1] - p1[0] * p1[0] - p1[1] * p1[1]);
for (int[] p : points) {
pq.offer(p);
if (pq.size() > K) {
pq.poll();
}
}
int size = Math.min(K, pq.size());
int[][] res = new int[size][2];
int i = size;
while (!pq.isEmpty()) {
res[--i] = pq.poll();
}
return res;
}
}
``````

#### Use Min-Heap

``````public static List<List<Integer>> topK(List<List<Integer>> input, int n,int m){
PriorityQueue<List<Integer>> pq = new PriorityQueue<List<Integer>>(n,
new Comparator<List<Integer>>(){
public int compare (List<Integer> e1,List<Integer> e2){
return e1.get(0)*e1.get(0) + e1.get(1)*e1.get(1) - e2.get(0)*e2.get(0) - e2.get(1)*e2.get(1);
}
});
for(List<Integer> e1:input){
}
List<List<Integer>> result = new ArrayList<>();
for(int i = 0;i < m && i < n;i++){
}
return result;
}
``````

## Reference

https://www.lintcode.com/problem/k-closest-points/description

Three solutions to this classical K-th problem. https://leetcode.com/problems/k-closest-points-to-origin/discuss/220235/Java-Three-solutions-to-this-classical-K-th-problem.