LeetCode : 973. K Closest Points to Origin K个距离远点最近的数

试题
We have a list of points on the plane. Find the K closest points to the origin (0, 0).

(Here, the distance between two points on a plane is the Euclidean distance.)

You may return the answer in any order. The answer is guaranteed to be unique (except for the order that it is in.)

Example 1:

Input: points = [[1,3],[-2,2]], K = 1
Output: [[-2,2]]
Explanation:
The distance between (1, 3) and the origin is sqrt(10).
The distance between (-2, 2) and the origin is sqrt(8).
Since sqrt(8) < sqrt(10), (-2, 2) is closer to the origin.
We only want the closest K = 1 points from the origin, so the answer is just [[-2,2]].
Example 2:

Input: points = [[3,3],[5,-1],[-2,4]], K = 2
Output: [[3,3],[-2,4]]
(The answer [[-2,4],[3,3]] would also be accepted.)

代码
最简单的就是堆排了。距离可以提前算好,堆存index,应该还可以降低时间。

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个最小数,显然如果使用快排我们的mid==K-1的话,那就找到了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;
    }
}
发布了557 篇原创文章 · 获赞 500 · 访问量 153万+

猜你喜欢

转载自blog.csdn.net/qq_16234613/article/details/100977189