难度: 中等
本节获得
- 构建任意数据结构大小根堆
const static bool cmp(const pair<int,int>&a,const pair<int,int>&b){ //比较函数
return a.first>b.first; //小根堆
}
priority_queue<pair<int,int>,vector<pair<int,int>>,decltype(&cmp)>q(cmp);//创建自定义排序的小根堆
priority_queue<Type,contain,function>q;
- 遍历键值对Map
for(auto &[a,b] : num){}//a是键,b是值
题目描述
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
示例1
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
提出时间复杂度小与O(nlog(n))的算法
解题思路
-
预处理每个元素出现的次数
-
用一个小根堆依次存入元素以及出现次数,
(a,b),a表示元素出现的次数,b表示元素值 -
分两种情况考虑
- 当堆内元素个数小与
k时,此时任何元素均可入栈,元素以及其出现的次数压入堆内 - 当堆内元素个数大于等于
k时,
(1)比较小根堆内元素出现次数是否比待入堆元素出现次数大
(2)不大,则排出堆顶元素,如新元素
(3)大,则舍弃当前待入堆元素
- 当堆内元素个数小与
-
最后堆内元素为
k个,将其导入返回数组,算法结束。
class Solution {
public:
const static bool cmp(const pair<int,int>&a,const pair<int,int>&b){
return a.first>b.first;
}
vector<int> topKFrequent(vector<int>& nums, int k) {
int n=nums.size();
vector<int>ans(k,0);
priority_queue<pair<int,int>,vector<pair<int,int>>,decltype(&cmp)>q(cmp);
unordered_map<int,int>num;
for(int i=0;i<n;i++){
num[nums[i]]++;
}
for(auto &[a,b] : num){
if(q.size()<k)q.push(make_pair(b,a));
else if(q.top().first<b){
q.pop();q.push(make_pair(b,a));
}
}
int index=0;
while(!q.empty()){
auto a=q.top();q.pop();
ans[index++]=a.second;
}
return ans;
}
};
算法复杂度
算法时间复杂度:O(nlog(k))<O(nlog(n))
算法空间复杂度:O(n)