Problems: https://leetcode.com/problems/k-closest-points-to-origin/
Solution1:
重点在于如何绑定点坐标和点到原点的距离
class Solution {
public int[][] kClosest(int[][] points, int K) {
int len = points.length;
int[] dists = new int[len];
for (int i=0; i<len; i++) {
dists[i] = dist(points[i]);
}
Arrays.sort(dists);
int max_dis = dists[K-1];
int[][] ans = new int[K][2];
int t = 0;// 注意points的索引i与ans的索引t的区别
for(int i = 0; i < len; i++) {
if(dist(points[i]) <= max_dis) {
ans[t++] = points[i];
}
}
return ans;
}
public int dist(int[] point) {
return point[0]*point[0] + point[1]*point[1];
}
}
Solution2:
maxheap:使用priorityqueue实现maxheap,maxheap的size为k
class Solution {
public int[][] kClosest(int[][] points, int K) {
PriorityQueue<int[]> maxHeap = 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++) {
maxHeap.add(points[i]);
if (maxHeap.size() > K) {
maxHeap.remove();
}
}
int[][] result = new int[K][2];
for(int i = 0; i < K; i++){
result[i] = maxHeap.remove();
}
return result;
}
}
Solution3:
use minheap and extract 2 min
class Solution {
public int[][] kClosest(int[][] points, int K) {
PriorityQueue<int[]> minHeap = new PriorityQueue<>((a,b) -> (a[0] * a[0] + a[1] * a[1]) - (b[0] * b[0] + b[1] * b[1]));
for (int i = 0; i < points.length; i++) {
minHeap.add(points[i]);
}
int[][] result = new int[K][2];
for(int i = 0; i < K; i++){
result[i] = minHeap.remove();
}
return result;
}
}
Solution4:
quick select
class Solution {
public int[][] kClosest(int[][] points, int K) {
int[] d = new int[points.length];
for(int i=0; i < d.length; i++) {
d[i] = dis(points[i]);
}
int target = quickSelect(d, 0, d.length-1, K);
int[][] ans = new int[K][2];
int t = 0;
for(int i = 0; i < d.length; i++) {
if (dis(points[i]) <= target) {
ans[t++] = points[i];
}
}
return ans;
}
public int quickSelect(int[] arr, int start, int end, int k) {
int left = start;
int right = end;
// Select pivot and swap pivot & end
Random rand = new Random();
int idx = rand.nextInt(end-start+1) + start;
int pivot = arr[idx];
swap(arr, idx, end);
// Rearrange left and right
while(left < right) {
if(arr[left++] >= pivot) {
swap(arr, --left, --right);
}
}
// Put pivot back to its place
swap(arr, left, end);
// Now left is the smallest number which equals or bigger than pivot
int m = left - start + 1; // m is the number of numbers that smaller than pivot
// pivot is the kth largest number
if(m == k) {
return pivot;
} else if(k < m) {
// target in left array
return quickSelect(arr, start, left-1, k);
} else {
return quickSelect(arr, left+1, end, k-m);
}
}
public int dis(int[] p) {
return p[0]*p[0] + p[1]*p[1];
}
public void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
Quick select reference: https://blog.csdn.net/Yaokai_AssultMaster/article/details/68878950