Poison

973. K Closest Points to Origin

Priority Queue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
private int getLength(int[] point) {
return point[0] * point[0] + point[1] * point[1];
}

public int[][] kClosest(int[][] points, int k) {
Queue<int[]> maxHeap = new PriorityQueue<>((o1, o2) -> getLength(o2) - getLength(o1));

for (int i = 0; i < k; i++) {
maxHeap.offer(points[i]);
}
for (int i = k; i < points.length; i++) {
if (getLength(points[i]) < getLength(maxHeap.peek())) {
maxHeap.poll();
maxHeap.offer(points[i]);
}
}

return maxHeap.toArray(new int[0][]);
}
}

注意需要使用大顶堆,堆底元素都比堆顶小,当后续遍历到更小元素时,弹出堆顶元素并放入堆中。

QuickSort + Two Pointers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class Solution {
private int getLength(int[] point) {
return point[0] * point[0] + point[1] * point[1];
}

public int[][] kClosest(int[][] points, int k) {
int targetIndex = k - 1;

int left = 0, right = points.length - 1;
while (true) {
int index = partition(points, left, right);
if (index < targetIndex) {
left = index + 1;
} else if (index > targetIndex) {
right = index - 1;
} else {
return Arrays.copyOf(points, k);
}
}
}

private int partition(int[][] points, int left, int right) {
int pivotIndex = left + ThreadLocalRandom.current().nextInt(right - left + 1);
int pivotLength = getLength(points[pivotIndex]);
swap(points, pivotIndex, left);

int lt = left + 1, rt = right;
while (true) {
while (lt <= rt && getLength(points[lt]) < pivotLength) {
lt++;
}
while (lt <= rt && getLength(points[rt]) > pivotLength) {
rt--;
}

if (lt > rt) {
break;
}

swap(points, lt++, rt--);
}

swap(points, rt, left);
return rt;
}

private void swap(int[][] points, int i, int j) {
int[] tmp = points[i];
points[i] = points[j];
points[j] = tmp;
}
}
Reference

973. K Closest Points to Origin