973. K Closest Points to Origin

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

题意:给出二维平面上的一系列点,求出距离原点(0,0)最近的K个点。

思路一:构造结构体,使用自定义排序函数的优先队列实现。

struct Node{
    int x,y;
    double dis;
    Node(int x,int y,double dis){
        this->x=x;
        this->y=y;
        this->dis=dis;
    }
};
// 排序函数 
bool operator<(Node a,Node b){
    return a.dis<b.dis;
}
class Solution {
public:
    // 自定义类型的优先队列  
    priority_queue<Node,vector<Node>,less<Node> >que;
    vector<vector<int>>ans;
    
    vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {
        for(int i=0;i<points.size();i++){
            double dis=sqrt(points[i][0]*points[i][0]+points[i][1]*points[i][1]);
            // 队列中元素个数<K 或者 该点距离更小时 入队。 
            if(que.size()<K)
                que.push(Node(points[i][0],points[i][1],dis));
            else if(dis<que.top().dis){
                que.pop();
                que.push(Node(points[i][0],points[i][1],dis));
            }
        }
        while(!que.empty()){
            vector<int>vv;
            vv.push_back(que.top().x);
            vv.push_back(que.top().y);
            que.pop();
            ans.push_back(vv);
        }
        return ans;
    }
};

思路二:使用STL中的partial_sort 部分排序函数

// STL中提供了一个部分排序函数  partial_sort
// 当对于问题规模较大,而我们仅仅需要最大或最小的K个元素时,可以使用partial_sort函数 
// partial_sort(begin,begin+K,end) 默认从小到大排序
// partial_sort(begin,begin+K,end,cmp) 在begin到end区间中,找出我们需要的K个元素按顺序放到
// begin到begin+K区间,后面的仍为无序。  注意:partial_sort得到的前K个是按序排列的
bool cmp(const vector<int>& a,const vector<int>& b)
{
    return a[0]*a[0]+a[1]*a[1]<b[0]*b[0]+b[1]*b[1];
}
class Solution {
public:
    vector<vector<int>> kClosest(vector<vector<int>>& points, int K) { 
//      partial_sort(points.begin(),points.begin()+K,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];
//         });                
        partial_sort(points.begin(),points.begin()+K,points.end(),cmp);
        return vector<vector<int>>(points.begin(),points.begin()+K);
    }
};

思路三:使用nth_element函数

// nth_element同样用于部分排序,但其获得的前K个元素是无序的。
bool cmp(const vector<int>& a,const vector<int>& b)
{
    return a[0]*a[0]+a[1]*a[1]<b[0]*b[0]+b[1]*b[1];
}
class Solution {
public:
    vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {               
        nth_element(points.begin(),points.begin()+K-1,points.end(),cmp);
        return vector<vector<int>>(points.begin(),points.begin()+K);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值