方法一:排序O(nlogn)
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)
class Solution {
public int[][] kClosest(int[][] points, int K) {
PriorityQueue<int[]> pq = new PriorityQueue<int[]>(new Comparator<int[]>() {
public int compare(int[] array1, int[] array2) {
return array2[0] - array1[0];
}
});
for (int i = 0; i < K; ++i) {
pq.offer(new int[]{points[i][0] * points[i][0] + points[i][1] * points[i][1], i});
}
int n = points.length;
for (int i = K; i < n; ++i) {
int dist = points[i][0] * points[i][0] + points[i][1] * points[i][1];
if (dist < pq.peek()[0]) {
pq.poll();
pq.offer(new int[]{dist, i});
}
}
int[][] ans = new int[K][2];
for (int i = 0; i < K; ++i) {
ans[i] = points[pq.poll()[1]];
}
return ans;
}
}
方法三,快排思想,下标为K之前的节点全都小于arr[k],最好情况下,O(n),最坏情况下O(n*n)
class Solution {
public int[][] kClosest(int[][] points, int K) {
QuickSort(points, 0, points.length-1, K-1);
return Arrays.copyOfRange(points, 0, K);
}
public void QuickSort(int[][] points, int left, int right, int K) {
if (left >= right) {
return;
}
int pivot = points[left][0] * points[left][0] + points[left][1] * points[left][1];
int[] index = points[left];
int l = left;
int r = right;
while (l < r) {
while (l < r && points[r][0] * points[r][0] + points[r][1] * points[r][1] >= pivot) {
r--;
}
points[l] = points[r];
while (l < r && points[l][0] * points[l][0] + points[l][1] * points[l][1] <= pivot) {
l++;
}
points[r] = points[l];
}
points[l] = index;
if (K < l) {
QuickSort(points, left, l - 1, K);
} else if (K > l) {
QuickSort(points, l + 1, right, K);
}
}
}