[Leetcode] 973. K Closest Points to Origin

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值