码迷,mamicode.com
首页 > 其他好文 > 详细

LeetCode 973 最接近原点的K个点

时间:2020-11-10 11:15:37      阅读:7      评论:0      收藏:0      [点我收藏+]

标签:queue   size   时间复杂度   pop   一个   tps   cto   public   这一   

LeetCode 973 最接近原点的K个点

https://leetcode-cn.com/problems/k-closest-points-to-origin/
?
这个题目比较简单,本质上是一个排序题。先把最简单的快速排序给安排上。

struct Point {
    int x;
    int y;
    int dist;
};
?
struct Compare {
    bool operator()(const Point &a, const Point &b) {
        return a.dist < b.dist;
    }
} cmp;
?
class Solution {
public:
    // 时间和空间复杂度:O(NlogN), O(N)
    vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {
        vector<Point> pts;
        for (vector<int>& p : points) {
            Point pp;
            pp.x = p[0];
            pp.y = p[1];
            pp.dist = pp.x * pp.x + pp.y * pp.y;
            pts.emplace_back(pp);
        }
?
        sort(pts.begin(), pts.end(), cmp);
        vector<vector<int>> ans;
        for (int i = 0; i < pts.size() && i < K; ++i) {
            vector<int> tmp;
            tmp.push_back(pts[i].x);
            tmp.push_back(pts[i].y);
            ans.emplace_back(tmp);
        }
        return ans;
    }
};

?
仔细一想,上述的快速排序代码可能并不是性能最优的。它有以下缺陷:
(1)使用了自定义的数据结构Point,里面除了平面点的横纵坐标之外还包含了它距离坐标原点欧氏距离的平方值。但这其实是没必要的,因为代码中用vector<int>存储点坐标,完全可以在这个vector<int>后面再push_back一个距离平方值即可。(注意:这违背了不修改函数输入这一原则)
(2)使用了额外的内存空间,可以在原始数据上进行排序(注意:这同样违背了不修改函数输入这一原则)
(3)在K值远远小于points中元素个数的情况下,对整个数组进行排序就显得得不偿失了,因为题目可能仅需要求出前几个离坐标原点比较近的点即可。
?
基于以上的分析,我们可以在原始数据上进行堆排序的方法给出另一种性能更好的解决方法。因为直接调用标准库中的优先队列,需要拷贝一份数据。所以空间复杂度还是没变。理论上的时间复杂度也没有变。虽然根据上面的分析下面的优先队列代码会比上面的快排更快一点,但是在力扣上的运行时间竟然比快排更久!看来理论和实际之间的鸿沟还是挺大的。

struct MyCompare {
    bool operator()(const vector<int>& a, const vector<int>& b) {
        return a[2] > b[2];
    }
};

class Solution {
public:
    vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {
        for (vector<int>& p : points) 
            p.push_back(p[0] * p[0] + p[1] * p[1]);
        
        priority_queue<vector<int>, vector<vector<int>>, MyCompare> pq(points.begin(), points.end());
        vector<vector<int>> ans;
        for (int i = 0; i < points.size() && i < K; ++i) {
            ans.push_back(pq.top());
            pq.pop();
        }

        // do NOT ignore this step
        for (vector<int>& p : ans)
            p.pop_back();

        return ans;
    }
};

LeetCode 973 最接近原点的K个点

标签:queue   size   时间复杂度   pop   一个   tps   cto   public   这一   

原文地址:https://www.cnblogs.com/wallace-lai/p/13951260.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!