1.暴力排序,新建节点类重载小于符号排序。

class Solution {
public:
struct comb{
int index,distance;
comb():index(0),distance(0){}
comb(int a,int b){
index=a;distance=b;
}
bool operator<(const comb& x){
return distance<x.distance;
}
};
vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {
if(points.size()<=K){
return points;
}
vector<comb> vec(points.size());
for(int i=0;i<points.size();++i){
vec[i]=comb(i,points[i][0]*points[i][0]+points[i][1]*points[i][1]);
}
sort(vec.begin(),vec.end());
vector<vector<int>> res(K);
for(int i=0;i<K;++i){
res[i]=points[vec[i].index];
}
return res;
}
};

其实我是想只对索引数组进行排序的,但sort的重载小于符函数不大好写,因为要用到points数组,没法加到函数参数里,所以就先这样写

2.快排划分。想到没必要全排序,因为只需要前k个。若当前划分好的小于K个,到右边再找。若等于K个或者K-1个,则输出。否则到左边缩小划分继续找,O(N logN)时间(大概是这个,具体不会算)。

class Solution {
public:
vector<vector<int>> kClosest(vector<vector<int>>& points, int K)
{
int siz = points.size();
if(K==siz)
{
return points;
}
vector<int> indexes(siz);
for (int i = 0; i < siz; ++i)
{
indexes[i] = i; //存索引
}
vector<vector<int>> res;
quicksort(indexes, points, 0, siz - 1, K, res);
return res;
}
void quicksort(vector<int>& indexes, vector<vector<int>>& points, int le, int ri, const int& K, vector<vector<int>>& res)
{
if (res.size() or le > ri)
{
return;
}
int mi = partition(indexes, points, le, ri, K);
if (mi == K - 1)
{
res.resize(K);
for (int i = 0; i < K; ++i)
{
res[i] = points[indexes[i]];
}
return;
}
else if (mi < K - 1) //目前找到最小的mi+1个,但mi+1<k,所以还要到右半边找k-mi+1个
{
quicksort(indexes, points, mi + 1, ri, K, res);
}
else //mi>k-1,则mi+1>k,左半边元素大于K个
{
quicksort(indexes, points, le, mi - 1, K, res);
}
}
int partition(vector<int>& indexes, vector<vector<int>>& points, int le, int ri, const int& K)
{
if(le==ri)
{
return le;
}
int p = le + rand() % (ri - le + 1);
int temp = indexes[p];
indexes[p] = indexes[ri];
indexes[ri] = temp;
int i = le - 1, j = le;
while (j < ri)
{
if (check(indexes[j], indexes[ri], points)) //索引j对应的点离原点比基准点近
{
int temp = indexes[j];
indexes[j] = indexes[++i];
indexes[i] = temp; //i先+1,再交换i、j处的索引值
}
++j;
}
temp = indexes[i + 1];
indexes[i + 1] = indexes[ri];
indexes[ri] = temp;
return i + 1; //返回基准数位置
}
bool check(int i, int j, vector<vector<int>>& points) //i、j为points的索引
{
if (abs(points[i][0]) < abs(points[j][0]) and abs(points[i][1]) < abs(points[j][1]))
{
return true;
}
return pow(points[i][0], 2) + pow(points[i][1], 2) < pow(points[j][0], 2) + pow(points[j][1], 2);
}
};

3.堆排。考虑到要求的前k个元素并不要求有序,故考虑建长度K的大顶堆,将所有点依次加入直到堆满。之后若当前元素比堆顶还大,丢弃该元素不用。最后留下来的K个就是最小的K个。这K个不是完全有序的,但确实是最小的K个。O(N logK)时间。

class Solution {
public:
static bool cmp(const vector<int>& a, vector<int>& b) {
return a[0] * a[0] + a[1] * a[1] < b[0] * b[0] + b[1] * b[1];
};
vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {
if (K >= points.size()) {
return points;
}
vector<vector<int>>res;
make_heap(res.begin(),res.end(),cmp); //大顶堆
for (auto& point : points) {
if (res.size() >= K) {
if(cmp(point,res[0])){ //当前point小于堆顶,pop堆顶,push当前point
pop_heap(res.begin(), res.end(),cmp);
res.pop_back();
res.push_back(point);
push_heap(res.begin(), res.end(), cmp);
}
}
else{
res.push_back(point);
push_heap(res.begin(), res.end(), cmp);
}
}
return res;
}
};

我看题解好像还有个神仙O(N)解法,没看,估计看了面试也背不出来,就这样。。2019年11月5日 15:23:24

973. 最接近原点的 K 个点的更多相关文章

  1. LeetCode——973. 最接近原点的 K 个点

    我们有一个由平面上的点组成的列表 points.需要从中找出 K 个距离原点 (0, 0) 最近的点. (这里,平面上两点之间的距离是欧几里德距离.) 你可以按任何顺序返回答案.除了点坐标的顺序之外, ...

  2. 【力扣】973. 最接近原点的 K 个点

    我们有一个由平面上的点组成的列表 points.需要从中找出 K 个距离原点 (0, 0) 最近的点. (这里,平面上两点之间的距离是欧几里德距离.) 你可以按任何顺序返回答案.除了点坐标的顺序之外, ...

  3. leetcode-973最接近原点的K个点

    leetcode-973最接近原点的K个点 题意 我们有一个由平面上的点组成的列表 points.需要从中找出 K 个距离原点 (0, 0) 最近的点. (这里,平面上两点之间的距离是欧几里德距离.) ...

  4. [Swift]LeetCode973. 最接近原点的 K 个点 | 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 d ...

  5. 最接近原点的K个点

    一.题目描述 我们有一个由平面上的点组成的列表 points.需要从中找出 K 个距离原点 (0, 0) 最近的点 这里,平面上两点之间的距离是欧几里德距离 你可以按任何顺序返回答案.除了点坐标的顺序 ...

  6. Leetcode973. K Closest Points to Origin最接近原点的K个点

    我们有一个由平面上的点组成的列表 points.需要从中找出 K 个距离原点 (0, 0) 最近的点. (这里,平面上两点之间的距离是欧几里德距离.) 你可以按任何顺序返回答案.除了点坐标的顺序之外, ...

  7. leetcode-973-最接近原点的K个点

    题目描述: 可参考:题215 方法一:排序 class Solution: def kClosest(self, points: List[List[int]], K: int) -> List ...

  8. LeetCode刷题总结-双指针、位运算和分治法篇

    本文总结LeetCode上有关双指针.位运算和分治法的算法题,推荐刷题总数14道.具体考点分析如下图: 一.双指针 1.字符串和数组问题 题号:424. 替换后的最长重复字符,难度中等 题号:828. ...

  9. LeetCode:堆专题

    堆专题 参考了力扣加加对与堆专题的讲解,刷了些 leetcode 题,在此做一些记录,不然没几天就忘光光了 力扣加加-堆专题(上) 力扣加加-堆专题(下) 总结 优先队列 // 1.java中有优先队 ...

随机推荐

  1. git三剑客笔记

    看了git三剑客视频总结的笔记,只给自己参考. 常用命令 查看分支:git branch 创建分支:git branch <name> 切换分支:git checkout <name ...

  2. CTF入门 |“男神”背后的隐写术

    刚刚开始学CTF,记录一下做的第一道隐写题 ~ 附件下载 题目背景(我自己瞎编的): Luyu是CPPU的校草,一直以来他的写真照被各届校友广泛流传,最近江湖上流传着拿到这些照片就能知道Luyu的QQ ...

  3. python创建字典的三种方式

    创建空字典: dict_eq={} print(type(dict)) 直接赋值创建字典: dict_eq={'a':1,'b':2,'c':'adbc'} 通过关键字dict和关键字参数创建 dic ...

  4. PP: DeepAR: probabilistic forecasting with autoregressive recurrent networks

    FROM Amazon research Germany PROBLEM probabilistic forecasting: estimate the probability distributio ...

  5. Linux系统初学者的常见问题解决集结大全

    http://www.embeddedlinux.org.cn/html/xinshourumen/200809/22-86.html 一. 如何建立多用户 提醒大家一句,别一直使用root用户,因为 ...

  6. 二分-B - Dating with girls(1)

    B - Dating with girls(1) Everyone in the HDU knows that the number of boys is larger than the number ...

  7. c++中vector函数

    std::vector <cv::Point> VectorPoints 说明:首先定义一个Point(即Point2i---二维整型的点)类型的变量VectorPoints,这就是我们创 ...

  8. Selenium(Webdriver)自动化测试常问问题

    http://blog.sina.com.cn/s/blog_c189e2590102w3bv.html Selenium(Webdriver)自动化测试常问问题 (1)selenium中如何保证操作 ...

  9. LED Decorative Light Supplier - LED Environmental Decorative Lighting Application

    Creating ambient lighting in the home can bridge the gap between the internal world and the outside ...

  10. pytest学习2-运行方式

    pytest常用运行方式 运行目录及子包下的所有用例: pytest 目录名 运行指定模块所有用例: pytest test_reg.py pytest test_reg.py::TestClass: ...