难度中等519
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2]
示例 2:
输入: nums = [1], k = 1 输出: [1]
解题思路
今天学习了之前听过的小顶堆、大顶堆,简单理解是每次动态维护K个元素,这K个元素在顶堆里面会自动进行排序。
小顶堆的话会每次弹出K个中最小的元素,最后堆中剩下的是K个最大的元素。
大顶堆的话每次弹出K个中最大的元素,最后堆中剩下的是K个最小元素。
还学到了优先队列的定义,刚看到是感到懵逼的,看不懂啥意思,就去查了一下priority_queue的定义,即
priority_queue<需要比较的类型type, 存放改类型的容器, 比较函数>
priority_queue<pair<int, int>, vector<pair<int, int>, myCompare> pri_queue;
那么每次放进pri_queue优先级队列的元素都会进行排序。
```cpp
class Solution {
public:
class myCompare{
public:
bool operator()(const pair<int, int> &lhs, const pair<int, int> &rhs){
return lhs.second > rhs.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
map<int, int> my_map;
for(int i = 0; i<nums.size(); i++){//用map记录每类元素对应的频率,对应map中的第二个int
my_map[nums[i]]++;
}
//小顶堆,对频率排序,把频率小的弹出去
priority_queue<pair<int, int>, vector<pair<int, int> >, myCompare> pri_queue;
//遍历my_map,将扫描所有频率,但pri_queue中只维护K个频率,超过就pop,因为
//小顶堆,每次pop出去的都是最小值,遍历完my_map,那么pri_que中剩下的就是K个最大频率
for( map<int, int>::iterator it = my_map.begin(); it != my_map.end(); it++){
pri_queue.push(*it); //必须先把值放进去,然后判断大小是否超过K
if(pri_queue.size() > k){
pri_queue.pop();
}
}
//此时pri_queue中已是由小到大的 k个频率,逆向遍历出来便是频率前K高的
vector<int> res(k);
for(int j = k-1; j>=0; j--){
res[j] = pri_queue.top().first;
pri_queue.pop();
}
return res;
}
};
```