題目來源:力扣
題目描述:
我們有一個由平面上的點組成的列表 points。需要從中找出 K 個距離原點 (0, 0) 最近的點。
(這裏,平面上兩點之間的距離是歐幾里德距離。)
你可以按任何順序返回答案。除了點座標的順序之外,答案確保是唯一的。
審題:
該題屬於典型的TopK問題,我們在之前已經討論過基於優先隊列的算法,求一堆元素中的TopK元素.在那篇文章中,我們手動使用堆結構實現了優先隊列.而在該文中,我們將直接使用java標準庫中的PriorityQueue
數據結構.PriorityQueue
數據結構中,最小的元素優先級最高.因此,爲了實現保存距離原點最近的K個點,我們需要設計優先隊列,距離原點最遠的點其優先級最高.因此對兩點進行比較,距離原點越遠,其優先級最高,該值最小.
java算法:
class Solution {
private class DistCmp implements Comparator<Integer[]>{
public int compare(Integer[]a, Integer[]b){
return Double.compare(Math.pow(b[0], 2) + Math.pow(b[1], 2),
Math.pow(a[0], 2) + Math.pow(a[1], 2));
}
}
public int[][] kClosest(int[][] points, int K) {
DistCmp cmp = new DistCmp();
PriorityQueue<Integer[]> pq = new PriorityQueue<>(10, cmp);
for(int i = 0; i < points.length; i++){
Integer[] point = new Integer[]{points[i][0], points[i][1]};
if(i < K)
pq.offer(point);
//如果當前point大於隊列中的第一個,則其優先級小於隊列中的最高優先級
else if(cmp.compare(point, pq.peek()) > 0){
pq.offer(point);
pq.poll();
}
}
int[][] nearK = new int[K][2];
for(int i = 0; i < K; i++){
Integer[] point = pq.poll();
nearK[i][0] = point[0];
nearK[i][1] = point[1];
}
return nearK;
}
}