题目描述 & 链接
Leetcode 973. K Closest Points to Origin
题目思路
1. 改写Comparator进行排序
这道题目思路比较直观,就是直接对每个点距离进行排序,取TopK个元素,这道题考察Java如何改写比较器。
class Solution {
public int[][] kClosest(int[][] points, int k) {
// comparator 改写
Arrays.sort(points, (int[] x, int[] y) -> {
long dis1 = x[0]*x[0]+x[1]*x[1];
long dis2 = y[0]*y[0]+y[1]*y[1];
if(dis1>dis2) return 1;
else if(dis1<dis2) return -1;
else return 0;
});
int[][] res = new int[k][2];
for(int i=0; i<k; i++) {
res[i] = points[i];
}
return res;
}
}
时间复杂度:;空间复杂度:
。
2. 快速选择
通过改写比较器进行排序,同样可以建立Heap插入选择TopK。对于选择TopK什么的还可以使用快速选择。快速选择的基本思路和模板可以参考[模板总结] - 快速选择 (霍尔Quick Selection)_ok1382038的博客-优快云博客
代码如下:
class Solution {
Random rand = new Random();
public int[][] kClosest(int[][] points, int k) {
// 找到topk大的值
quickSelect(points, 0, points.length-1, k);
return Arrays.copyOfRange(points, 0, k);
}
private void quickSelect(int[][] points, int start, int end, int k) {
if(start>end) return;
int l = start, r = end;
int mid = start + rand.nextInt(end - start + 1);;
int pivot = points[mid][0]*points[mid][0] + points[mid][1]*points[mid][1];
while(l<=r) {
while(l<=r && points[l][0]*points[l][0] + points[l][1]*points[l][1]<pivot) l++;
while(l<=r && points[r][0]*points[r][0] + points[r][1]*points[r][1]>pivot) r--;
if(l<=r) {
int[] temp = points[l];
points[l] = points[r];
points[r] = temp;
l++; r--;
}
if(k<=r) quickSelect(points, start, r, k);
else quickSelect(points, l, end, k);
}
}
}
时间复杂度:,最坏情况:
;空间复杂度:
, 递归的空间深度。