Leetcode笔记目录
一、题目描述
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例1:
- 输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例2:
- 输入: nums = [1], k = 1
输出: [1]
二、解题过程
1.思想
典型的TOPK问题,只要将频率hash,就变成Leetcode215,难点在于如何处理hash的map结构,使其能用TOPK问题的算法:
- 可以将map结构变为vector<pair<int,int>>,方便遍历和比较;
- 变成vector后使用快速选择或堆排序都比较方便,注意本题是前K个,而优先队列是无法遍历的(如果一直pop会很慢),所以使用自己实现的堆会比较好。
2.代码
堆排序版本:
void PercDown(vector<pair<int,int>>& nums, int p, int size){
int parent,child;
auto x = nums[p];
for(parent=p;parent*2+1<size;parent=child){
child=parent*2+1;
if(child!=size-1&&nums[child].second>nums[child+1].second)child++;
if(nums[child].second>x.second)break;
else nums[parent]=nums[child];
}
nums[parent]=x;
}
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int> map;
for (int i=0; i<nums.size();i++) {
map[nums[i]]++;
}
vector<pair<int,int>> mid;
vector<int> result;
for(auto it:map) mid.push_back(it);
for(int i=k/2-1;i>=0;i--) PercDown(mid,i,k);
for(int i=k;i<mid.size();i++){
if(mid[0].second<mid[i].second){
mid[0]=mid[i];
PercDown(mid,0,k);
}
}
for(int i=0;i<k;i++) result.push_back(mid[i].first);
return result;
}
- 注意
- 如何将map结构变成vector<pair<int,int>>。
- vector<pair<int,int>>结构下的覆盖:mid[0]=mid[i];及如何取值mid[0].first,mid[0].second。
三、总结
与Leetcode215十分相似。