「这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战」
说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)
作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题意描述
我们有一个由平面上的点组成的列表 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]] 也会被接受。)
分析
其实仔细阅读题目我们可以发现这题和前 K 个高频元素,很相似,只是那题是求前k的高频元素,本题呢,其实是求前k的低频元素。套路都是一样一样的。
我们肯定先想到快排,其实快排的话把所有元素都排序了,时间复杂度是O(nlogn),我们其实可以使用优先级队列时间复杂度为O(nlogk),因为只需要维护k个元素有序。下面在说说不一样的解法。
解法1:Map
思路:将每个点的距离存在map中,再排序。OK了
var kClosest = function(points, K) {
let map = new Map();
let res = [];
for(let i = 0;i<points.length;i++){
const value = points[i][0]*points[i][0]+points[i][1]*points[i][1];
map.set(i,value);
}
let ary = Array.from(map);
ary.sort((a,b) => {
return a[1] - b[1];
})
for(let i =0;i<K;i++){
res.push(points[ary[i][0]]);
}
return res;
};
解法2:优先队列
思路:可以直接将point加入优先队列中,通过维护K个值就OK了
class Solution {
public:
struct tmp2
{
bool operator() (pair<int,int> a, pair<int,int> b)
{
return pow(a.first,2)+pow(a.second,2) > pow(b.first,2)+pow(b.second,2);
}
};
vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {
vector<vector<int>> res;
if(K == points.size())
return points;
if(K > points.size())
return res;
priority_queue<pair<int,int>,vector<pair<int, int>>,tmp2> heap;
for(int i=0; i<points.size(); i++)
{
heap.push({points[i][0],points[i][1]});
}
for(int i=0; i<K; i++)
{
res.push_back(vector<int>{heap.top().first,heap.top().second});
heap.pop();
}
return res;
}
};
感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。
写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤