试题
私たちは、平面上の点のリストを持っています。原点(0、0)にK最も近いポイントを探します。
(ここでは、平面上の2点間の距離はユークリッド距離です。)
あなたは、任意の順序で答えを返すことがあります。答えは一意であることが保証されている(それがであることを順序を除きます。)
例1:
入力:点= [1,3]、[ - 2,2]、K = 1
出力:[-2,2]
説明:
(1、3)と原点との距離がSQRT(10) 。
(-2、2)と原点との間の距離は、SQRT(8)です。
SQRTので(8)<SQRT(10)、(-2、2)原点に近いです。
答えはちょうど[[-2,2]であるので、私たちは、原点から最も近いK = 1ポイントが欲しいです。
例2:
入力:点= [3,3]、[5、-1]、[ - 2,4]、K = 2
出力:[3,3]、[ - 2,4]
(回答[ -2,4]、[3,3]も受け入れられるだろう。)
コード
の最も簡単なヒープ行にあります。インデックスを備蓄、良い距離先に考えることができ、それはまた、時間を短縮する必要があります。
class Solution {
public int[][] kClosest(int[][] points, int K) {
PriorityQueue<int[]> queue = new PriorityQueue<int[]>(K, (int[] a, int[] b) -> euclidean(b).compareTo(euclidean(a)) );
for(int[] point : points){
queue.offer(point);
if(queue.size() > K){
queue.poll();
}
}
return queue.toArray(new int[0][0]);
}
public Double euclidean(int[] a){
int sum = 0;
for(int i = 0; i < a.length; i++){
sum += a[i] * a[i];
}
return Math.sqrt(sum);
}
}
タイトルは単にあなたが速く使い明らか場合は、当社の中期== K-1を放電し、Kの最小数を返し、規則的な配列に戻すために私たちを必要としないので、それはK最小の番号を見つけました。
class Solution {
int[][] points;
public int[][] kClosest(int[][] points, int K) {
this.points = points;
QuickSort(0, points.length - 1, K-1);
return Arrays.copyOfRange(points, 0, K);
}
public void QuickSort(int i, int j, int K) {
while(i < j){
int mid = partition(i, j);
if(mid == K){
return;
}else if(mid < K){
i = mid + 1;
}else if(mid > K){
j = mid - 1;
}
}
}
public int partition(int i, int j) {
int pivot = dist(i);
int left = i, right = j;
while (left < right) {
while (left < right && dist(right) >= pivot)
right--;
while (left < right && dist(left) <= pivot)
left++;
if(left < right)
swap(left, right);
}
swap(i, right);
return right;
}
public int dist(int i) {
return points[i][0] * points[i][0] + points[i][1] * points[i][1];
}
public void swap(int i, int j) {
int[] tmp = points[j];
points[j] = points[i];
points[i] = tmp;
return;
}
}