我们有一个由平面上的点组成的列表 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
大牛都是300ms都嫌慢的,我这是别人4倍...(实现复杂了)
思路:
1.构建包含K个数的最大堆,如果后续增加的数有比最大值小的话,则弹出堆顶,遍历整个数组即为最小的K个数 。
2.为了实现排序数和坐标点的映射,建了一个结构体,去存储实现结构体的排序。
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <map>
using namespace std;
class Solution {
public:
struct point {
int val;
vector<int> spot;
};
vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {
vector<vector<int>> res;
vector<point *> pointVec;
for (int i = 0; i < points.size(); i++) {
point* node = new point();
vector<int> vec = points[i];
node->val = vec[0] * vec[0] + vec[1] * vec[1];
node->spot = vec;
pointVec.push_back(node);
}
vector<point *>BottomVec = GetBottomK(pointVec, K);
for (int i = 0; i < BottomVec.size(); i++) {
res.push_back(BottomVec[i]->spot);
}
return res;
}
vector<point *> GetBottomK(vector<point *>& pointVec, int K) {
vector<point*> BottomVec;
BottomVec.assign(pointVec.begin(), pointVec.begin() + K);
buildKHeap(BottomVec, BottomVec.size());
for (int i = K; i < pointVec.size(); i++) {
if (pointVec[i]->val < BottomVec[0]->val) {
BottomVec[0] = pointVec[i];
buildKHeap(BottomVec, BottomVec.size());
}
}
return BottomVec;
}
//void maxHeapSort(vector<int>& arr, int len) {
// for (int i = len / 2 - 1; i >= 0; i--) {
// maxHeap(arr, i, len - 1);
// }
// for (int i = len - 1; i > 0; i--) {
// swap(arr[0], arr[i]);
// maxHeap(arr, 0, i - 1);
// }
//}
private:
void maxHeap(vector<point *>& arr, int start, int end) {
int dad = start;
int son = 2 * dad + 1;
while (son <= end) {
if (son + 1 <= end && arr[son]->val < arr[son + 1]->val) {
son++;
}
if (arr[dad]->val > arr[son]->val) {
return;
}
else {
swap(arr[dad], arr[son]);
dad = son;
son = 2 * dad + 1;
}
}
}
void buildKHeap(vector<point *>& arr, int len) {
for (int i = len / 2 - 1; i >= 0; i--) {
maxHeap(arr, i, len - 1);
}
}
};
int main() {
Solution* ps = new Solution();
vector<vector<int>> data1 = { {1,3},{-2,2} };
vector<vector<int>> data2 = { {3,3},{5,-1},{-2,4} };
vector<vector<int>> data3 = { {0,1},{1,0} };
vector<vector<int>> data4 = { {6,10},{-3,3},{-2,5},{0,2} };
vector<vector<int>> data5 = { {3, 3},{5, -1},{-2, 4} };
vector<vector<int>> res = ps->kClosest(data5, 2);
for (int i = 0; i < res.size(); i++) {
auto it = res[i];
for (int j = 0; j < it.size(); j++) {
cout << it[j] << ",";
}
cout << endl;
}
system("pause");
return 0;
}