【刷题打卡】973. 最接近原点的 K 个点

130 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、题目描述:

973. 最接近原点的 K 个点 - 力扣(LeetCode) (leetcode-cn.com)

给定一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点,并且是一个整数 k ,返回离原点 (0,0) 最近的 k 个点。

这里,平面上两点之间的距离是 欧几里德距离( √(x1 - x2)2 + (y1 - y2)2 )。

你可以按 任何顺序 返回答案。除了点坐标的顺序之外,答案 确保唯一 的。

 

示例 1:

image.png

输入:points = [[1,3],[-2,2]], k = 1
输出:[[-2,2]]
解释: 
(1, 3) 和原点之间的距离为 sqrt(10),
(-2, 2) 和原点之间的距离为 sqrt(8),
由于 sqrt(8) < sqrt(10),(-2, 2) 离原点更近。
我们只需要距离原点最近的 K = 1 个点,所以答案就是 [[-2,2]]

示例 2:

输入:points = [[3,3],[5,-1],[-2,4]], k = 2
输出:[[3,3],[-2,4]]
(答案 [[-2,4],[3,3]] 也会被接受。)

 

提示:

  • 1 <= k <= points.length <= 104
  • -104 < xi, yi < 104

二、思路分析:

本质上和找第K大元素的思路是一样的,使用快排中的partition方法,可以快速找到第pivot+1大(pivot是方法返回的下标)的元素,时间复杂度是O(n),然后根据返回的pivot和 k 比较,采取类似二分查找的策略再分段筛查,直到返回了下标是k-1的pivot,也就是这个位置就是第k大,将其前面(包括这个)的元素返回即可。

这里有一点不一样的地方是比较大小的时候是算距离圆心的记录,勾股定理就好了。

三、AC 代码:

class Solution {
    public int[][] kClosest(int[][] points, int k) {
        int length = points.length;
        int start = 0;
        int end = length - 1;
        int pivot;
        while(true) {
            pivot = partition(points, start, end);
            if (pivot == k - 1) {
                break;
            } else if (pivot > k - 1) {
                end = pivot - 1;
            } else if (pivot < k - 1) {
                start = pivot + 1;
            }
        }
        int[][] result = new int[k][];
        for (int i = 0; i < k; i ++) {
            result[i] = points[i];
        }
        return result;
    }

    private int partition(int[][] points, int start, int end) {
        int pivot = start;
        for (int i = start; i <= end; i ++) {
            if (compare(points[i], points[end]) <= 0) {
                int[] tmp = points[pivot];
                points[pivot] = points[i];
                points[i] = tmp;
                pivot ++;
            }
        }
        return pivot - 1;
    }

    private int compare(int[] p1, int[] p2) {
        return p1[0] * p1[0] + p1[1] * p1[1]
               - p2[0] * p2[0] - p2[1] * p2[1];
    }
}