Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LeetCode] 973. K Closest Points to Origin #973

Open
grandyang opened this issue May 30, 2019 · 0 comments
Open

[LeetCode] 973. K Closest Points to Origin #973

grandyang opened this issue May 30, 2019 · 0 comments

Comments

@grandyang
Copy link
Owner

grandyang commented May 30, 2019

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.)

Note:

  1. 1 <= K <= points.length <= 10000
  2. -10000 < points[i][0] < 10000
  3. -10000 < points[i][1] < 10000

这道题给了平面上的一系列的点,让求最接近原点的K个点。基本上没有什么难度,无非就是要知道点与点之间的距离该如何求。一种比较直接的方法就是给这个二维数组排序,自定义排序方法,按照离原点的距离从小到大排序,注意这里我们并不需要求出具体的距离值,只要知道互相的大小关系即可,所以并不需要开方。排好序之后,返回前k个点即可,参见代码如下:

解法一:

class Solution {
public:
    vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {
        sort(points.begin(), points.end(), [](vector<int>& a, vector<int>& b) {
        	return a[0] * a[0] + a[1] * a[1] < b[0] * b[0] + b[1] * b[1];
        });
        return vector<vector<int>>(points.begin(), points.begin() + K);
    }
};

下面这种解法是使用最大堆 Max Heap 来做的,在 C++ 中就是用优先队列来做,这里维护一个大小为k的最大堆,里面放一个 pair 对儿,由距离原点的距离,和该点在原数组中的下标组成,这样优先队列就可以按照到原点的距离排队了,距离大的就在队首。这样每当个数超过k个了之后,就将队首的元素移除即可,最后把剩下的k个点存入结果 res 中即可,参见代码如下:

解法二:

class Solution {
public:
    vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {
        vector<vector<int>> res;
        priority_queue<pair<int, int>> pq;
        for (int i = 0; i < points.size(); ++i) {
            int t = points[i][0] * points[i][0] + points[i][1] * points[i][1];
            pq.push({t, i});
            if (pq.size() > K) pq.pop();
        }
        while (!pq.empty()) {
            auto t = pq.top(); pq.pop();
            res.push_back(points[t.second]);
        }
        return res;
    }
};

Github 同步地址:

#973

类似题目:

Kth Largest Element in an Array

Top K Frequent Elements

Top K Frequent Words

参考资料:

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

https://leetcode.com/problems/k-closest-points-to-origin/discuss/217999/JavaC%2B%2BPython-O(N)

https://leetcode.com/problems/k-closest-points-to-origin/discuss/221532/C%2B%2B-STL-quickselect-priority_queue-and-multiset

https://leetcode.com/problems/k-closest-points-to-origin/discuss/220235/Java-Three-solutions-to-this-classical-K-th-problem.

LeetCode All in One 题目讲解汇总(持续更新中...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant