Files
leetcode-master/problems/0973.最接近原点的K个点.md
youngyangyang04 7aeab97252 Update
2020-11-10 10:01:41 +08:00

3.5 KiB
Raw Blame History

思路

这道题其实我在讲解队列的时候,就已经讲过了,在栈与队列:求前 K 个高频元素和队列有啥关系?中,我介绍了一种队列, 优先级队列,其实就是大(小)顶堆。

大家有精力的话也可以做做347.前 K 个高频元素347是求前k的高频元素本题呢其实是求前k的低频元素。

所以套路都是一样一样的。

有的同学会用快排其实快排的话把所有元素都排序了时间复杂度是O(nlogn)而使用优先级队列时间复杂度为O(nlogk)因为只需要维护k个元素有序。

然后就是为什么要定义大顶堆呢?

因为本地要求最小k个数每次添加堆都是从顶部把最大的弹出去然后堆里留下的就是最小的k个数了。

C++代码如下:

// 版本一
class Solution {
public:
    // 大顶堆比较函数
    class mycomparison {
    public:
        bool operator()(const pair<int, vector<int>>& lhs, const pair<int, vector<int>>& rhs) {
            return lhs.first < rhs.first;
        }
    };
    vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {
        // 定义一个大顶堆
        priority_queue<pair<int, vector<int>>, vector<pair<int, vector<int>>>, mycomparison> pri_que;
        for(int i = 0; i < points.size(); i++) {
            int x = points[i][0];
            int y = points[i][1];
            pair<int, vector<int>> p(x * x + y * y, points[i]); // key:距离value是(x,y)
            pri_que.push(p);
            if (pri_que.size() > K) { // 如果队列的大小大于了K则队列弹出保证队列的大小一直为k
                pri_que.pop();
            }
        }
        vector<vector<int>> result(K); // 把队列里元素放入数组
        for (int i = 0; i < K; i++) {
            result[i] = pri_que.top().second;
            pri_que.pop();
        }
        return result;
    }
};

以上是为了完整的体现出优先级队列的定义以及比较过程。

如果要简化一下,就用默认的配置就可以。代码如下:

// 版本二
class Solution {
public:
    vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {
        // 默认大顶堆按照pair的key排序
        priority_queue<pair<int, vector<int>>, vector<pair<int, vector<int>>>> pri_que;
        for(int i = 0; i < points.size(); i++) {
            int x = points[i][0];
            int y = points[i][1];
            pair<int, vector<int>> p(x * x + y * y, points[i]); // key:距离value是(x,y)
            pri_que.push(p);
            if (pri_que.size() > K) { // 如果队列的大小大于了K则队列弹出保证队列的大小一直为k
                pri_que.pop();
            }
        }
        vector<vector<int>> result(K); // 把队列里元素放入数组
        for (int i = 0; i < K; i++) {
            result[i] = pri_que.top().second;
            pri_que.pop();
        }
        return result;
    }
};

我是程序员Carl,组队刷题可以找我,本文leetcode刷题攻略已收录,更多精彩算法文章尽在:代码随想录,期待你的关注!