LeetCode 973. 最接近原点的 K 个点(排序/优先队列/快排)
发布日期:2021-07-01 03:25:13
浏览次数:2
分类:技术文章
本文共 3314 字,大约阅读时间需要 11 分钟。
文章目录
1. 题目
我们有一个由平面上的点组成的列表 points。需要从中找出 K 个距离原点 (0, 0) 最近的点。
(这里,平面上两点之间的距离是欧几里德距离。)
你可以按任何顺序返回答案。除了点坐标的顺序之外,答案确保是唯一的。
示例 1:输入: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 <= 10000-10000 < points[i][0] < 10000-10000 < points[i][1] < 10000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/k-closest-points-to-origin 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2. 解题
类似题目:
2.1 排序
class Solution { public: vector> kClosest(vector >& points, int K) { if(K == points.size()) return points; sort(points.begin(),points.end(),[&](auto a, auto b){ return a[0]*a[0]+a[1]*a[1] < b[0]*b[0]+b[1]*b[1]; }); points.resize(K); return points; }};
1772 ms 191.6 MB
partial_sort 只对前部分[first,middle)进行排序,前部分实现为堆
class Solution { public: vector> kClosest(vector >& points, int K) { partial_sort(points.begin(), points.begin() + K, points.end(), [&] (auto a, auto b){ return a[0]*a[0]+a[1]*a[1] < b[0]*b[0]+b[1]*b[1]; }); points.resize(K); return points; }};
1552 ms 148.4 MB
时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)2.2 优先队列
- 维持一个容量为K的大顶堆
- 队列满了,后续点比堆顶更接近原点时,pop堆顶,push当前点
struct cmp{ bool operator()(const vector & a, const vector & b)const { return a[0]*a[0]+a[1]*a[1] < b[0]*b[0]+b[1]*b[1];//大顶堆 }};class Solution { public: vector> kClosest(vector >& points, int K) { if(K == points.size()) return points; priority_queue , vector >, cmp> q; for(int i = 0; i < points.size(); ++i) { if(q.size() < K) q.push(points[i]); else if(q.top()[0]*q.top()[0]+q.top()[1]*q.top()[1] > points[i][0]*points[i][0]+points[i][1]*points[i][1]) { q.pop(); q.push(points[i]); } } vector > ans(q.size()); int i = 0; while(!q.empty()) { ans[i++] = q.top(); q.pop(); } return ans; }};
时间复杂度 O ( n l o g K ) O(nlogK) O(nlogK)
628 ms 47.5 MB2.3 快排思路
class Solution { public: vector> kClosest(vector >& points, int K) { if(K == points.size()) return points; findkth(points,0,points.size()-1,K); points.resize(K); return points; } int dis(vector >& points, int i) { return points[i][0]*points[i][0]+points[i][1]*points[i][1]; } void findkth(vector >& points,int l, int r, int K) { int i = l, j = r, p = dis(points, l); while(i < j) { while(i < j && dis(points,j) > p)//必须先从右边开始,因为选的pivot在左边 j--; while(i < j && dis(points,i) <= p) i++; swap(points[i], points[j]); } swap(points[l], points[i]); if(i < K)//左边都是答案的一部分,取右边找 findkth(points,i+1,r,K); else if(i > K)//左边多于K个,在左边继续分割 findkth(points,l,i-1,K); else return; }};
时间复杂度 O ( n ) O(n) O(n)
244 ms 39 MB转载地址:https://michael.blog.csdn.net/article/details/105969787 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
网站不错 人气很旺了 加油
[***.192.178.218]2024年04月14日 15时50分17秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
浅谈数据库高可用性(HA)技术
2019-05-02
许式伟的架构课
2019-05-02
Linux调试工具
2019-05-02
用Eclipse和GDB构建ARM交叉编译和在线调试环境
2019-05-02
cfs 完全公平调度
2019-05-02
如何判断自己是否具有成为一名优秀程序员的潜质
2019-05-02
创业公司和求职者都应看的九个面试题
2019-05-02
内核的链接脚本文件vmlinux.lds.S
2019-05-02
Ubuntu下 rsync同步文件实例
2019-05-02
安装Samba时遇到错误
2019-05-02
Linux Shell编程入门
2019-05-02
EMACS利用etags查阅大型工程代码
2019-05-02
C++名稱空間(Namespace)的介绍
2019-05-02
通过源码查看Android 版本
2019-05-02
getopts命令详解
2019-05-02
Java接口详解
2019-05-02
gprof使用
2019-05-02
详细解析Java中抽象类和接口的区别
2019-05-02
Python模块学习 ---- datetime
2019-05-02