[LeetCode] 973. K Closest Points to Origin

题:https://leetcode.com/problems/k-closest-points-to-origin/

题目大意

对于 数组int[][] points,找出 前 K个 离原点最近的 点。

思路大意

大堆求前k个小的点

可以使用 小堆,然后 取 先 k 个数。但这个 O(nlogn)。
使用 大 堆,只用 O(nlogk),堆变小些。

维护一个大堆,当堆容量 小于 k,将 point 直接加入。
若大于 k,将堆顶 与 新point 比较,若新point 较小,将堆顶删除,将新point加入。

class Solution {
    public int[][] kClosest(int[][] points, int K) {
        PriorityQueue<int []> priorityqueue = new PriorityQueue<>(new Comparator<int[]>(){
            public int compare(int[] o1,int[] o2){
                return -((o1[0]*o1[0] + o1[1]*o1[1]) - (o2[0]*o2[0] + o2[1]*o2[1])); 
            }
        });
        for(int[] point:points){
            if(priorityqueue.size()<K)
                priorityqueue.add(point);
            else{
                if(priorityqueue.peek()[0]*priorityqueue.peek()[0]+ priorityqueue.peek()[1]*priorityqueue.peek()[1]>
                        point[0]*point[0] +point[1]*point[1]){
                    priorityqueue.poll();
                    priorityqueue.add(point);
                }
            }
        }
        int[][] resPoints = new int[K][2];
        for(int i = 0 ; i < resPoints.length ; i++)
            resPoints[i] = priorityqueue.poll();
        return resPoints;
    }
}

使用 快排序的 patition 函数

class Solution {
    public int[][] kClosest(int[][] points, int K) {
        int l = 0,r = points.length -1;
        int k = K-1;
        while(l < r){
            int p = partition(points,l,r);
            if(p < k){
                l = p + 1;
            }else if(p>k){
                r = p -1;
            }else 
                break;
        }
        int[][] resPoints = new int[K][];
        for(int i = 0 ; i < K ; i++)
            resPoints[i] = points[i];
        return resPoints;
    }
    void swap(int[][] points ,int a,int b){
        int[] tmp = points[a];
        points[a] = points[b];
        points[b] = tmp;
    }

    private int partition(int[][] points, int l, int r) {
        int il = l ,ir = r;
        int pivot = points[l][0]*points[l][0] + points[l][1]*points[l][1];
        while (il<ir){
            while(il<ir && points[ir][0]*points[ir][0] + points[ir][1]*points[ir][1]>pivot)
                ir--;
            while(il<ir && points[il][0]*points[il][0] + points[il][1]*points[il][1]<=pivot)
                il++;
            swap(points,il,ir);
        }
        swap(points,l,il);
        return il;
    }
}

猜你喜欢

转载自blog.csdn.net/u013383813/article/details/86438414