LeetCode 973. 最接近原點的 K 個點
本文總結了兩個方法:
- 方法一為本人所使用的直接排序方法,簡單易實作;
- 方法二使用了優先隊列這一資料結構,耗時更短。
方法一:排序
重寫
cmp()
函數,使用
sort()
進行直接排序。
代碼
class Solution {
public:
static bool cmp(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) {
sort(points.begin(), points.end(), cmp);
return {points.begin(), points.begin() + K};
}
};
方法二:優先隊列
優先隊列具有隊列的所有特性,包括基本操作,隻是在這基礎上添加了内部的一個排序,它本質是一個堆實作的,它和queue不同的就在于我們可以自定義其中資料的優先級, 讓優先級高的排在隊列前面,優先出隊。
而對于
的隊列,會先比較第一個元素,若第一個相等再比較第二個。
pair
使用一個優先隊列(大根堆)實時維護前 K 個最小的距離平方。
将前 K 個點的距離平方以及對應的編号(為了友善最後直接得到答案)放入優先隊列中。
随後從第 K+1 個點開始周遊:如果目前點的距離平方比堆頂的點的距離平方要小,就把堆頂(因為是大根堆)的點彈出,再插入目前的點。
當周遊完成後,所有在優先隊列中的點就是前 K 個距離最小的點。
不同的語言提供的優先隊列的預設情況不一定相同。在 C++ 語言中,優先隊列預設為大根堆。
代碼
class Solution {
public:
vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {
priority_queue<pair<int, int>> q;
for (int i = 0; i < K; ++i) {
q.emplace(points[i][0] * points[i][0] + points[i][1] * points[i][1], i);
}
int n = points.size();
for (int i = K; i < n; ++i) {
int dist = points[i][0] * points[i][0] + points[i][1] * points[i][1];
if (dist < q.top().first) {
q.pop();
q.emplace(dist, i);
}
}
vector<vector<int>> ans;
while (!q.empty()) {
ans.push_back(points[q.top().second]);
q.pop();
}
return ans;
}
};
原題傳送門