# 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.