---
# System prepended metadata

title: 0973. K Closest Points to Origin
tags: [Leetcode, FaceBook, Medium, QuickSort]

---

# 0973. K Closest Points to Origin
###### tags: `Leetcode` `Medium` `QuickSort` `FaceBook`
Link: https://leetcode.com/problems/k-closest-points-to-origin/
## 思路
### 思路一
暴力排序
### 思路二
Priority Queue 
### 思路三
Quick Sort
## Code
### 思路一 O(NlogN) & O(logN)
```java=
class Solution {
    public int[][] kClosest(int[][] points, int k) {
        Arrays.sort(points, new Comparator<int[]>() {
            public int compare(int[] point1, int[] point2) {
                return (point1[0] * point1[0] + point1[1] * point1[1]) - (point2[0] * point2[0] + point2[1] * point2[1]);
            }
        });
        return Arrays.copyOfRange(points, 0, k);
    }
}
```
### 思路二 O（Nlogk) & O(k) (大根堆里有k个点)
```java=
class Solution {
    public int[][] kClosest(int[][] points, int k) {
        PriorityQueue<int[]> pq = new PriorityQueue<>((a,b) -> (b[0]*b[0]+b[1]*b[1]-a[0]*a[0]-a[1]*a[1]));
        for(int i = 0;i < points.length;i++){
            if(pq.size()<k){
                pq.offer(points[i]);
            }
            else if(pq.comparator().compare(points[i],pq.peek())>0){
                pq.poll();
                pq.offer(points[i]);
            }
        }
        int[][] res = new int[pq.size()][2];
        int idx = 0;
        for(int[] point:pq){
            res[idx++] = point;
        }
        return res;
    }
}

```
### 思路三 （期望为 O(N) & O(logN)）
```java=
class Solution {
    static Random rand = new Random();
    public int[][] kClosest(int[][] points, int k) {
        int n = points.length;
        randomSelect(points, 0, n-1, k);
        return Arrays.copyOfRange(points, 0,k);
    }
    public static void randomSelect(int[][] points, int left, int right, int k){
        int pivotId = left + rand.nextInt(right - left + 1);
        int pivot = points[pivotId][0] * points[pivotId][0] + points[pivotId][1] * points[pivotId][1];
        swap(points, right, pivotId);
        int i = left - 1;
        for (int j = left; j < right; ++j) {
            int dist = points[j][0] * points[j][0] + points[j][1] * points[j][1];
            if (dist <= pivot) {
                ++i;
                swap(points, i, j);
            }
        }
        ++i;
        swap(points, i, right);
        // [left, i-1] 都小于等于 pivot, [i+1, right] 都大于 pivot
        if (k < i - left + 1) {
            randomSelect(points, left, i - 1, k);
        } else if (k > i - left + 1) {
            randomSelect(points, i + 1, right, k - (i - left + 1));
        }
    }

    public static int computeDist(int[][] points, int index){
        return points[index][0]*points[index][0]+points[index][1]*points[index][1];
    }
    public static void swap(int[][] points, int a, int b){
        int[] temp = points[a];
        points[a] = points[b];
        points[b]  = temp;
    }
}

```
## Result
### 思路一
Runtime: 15 ms, faster than **82.60%** of Java online submissions for K Closest Points to Origin.
Memory Usage: 47.3 MB, less than **88.53%** of Java online submissions for K Closest Points to Origin.
### 思路二
Runtime: 3 ms, faster than **98.69%** of Java online submissions for K Closest Points to Origin.
Memory Usage: 47.7 MB, less than **63.94%** of Java online submissions for K Closest Points to Origin.