题目描述
给你一个整数数组 nums
和一个整数 k
,请你返回其中出现频率前 k
高的元素。你可以按 任意顺序 返回答案。
举例
# 例1
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
# 例2
输入: nums = [1], k = 1
输出: [1]
解题思路
1、首先统计数组中每个元素出现的频率,可以使用 map
2、然后将元素和它对应的频率,以键值对的形式 添加到 优先队列中(小根堆),然后保留优先队列中的后 k
个元素
3、这时候优先队列中的 k
个元素就是要找的结果,要把队列中的键值对中的键倒序依次取出,然后保存到一个数组中,该数组就是最后的结果
代码
(C++)
#include <iostream>
#include <vector>
#include <unordered_map>
#include <queue>
using namespace std;
class Solutional {
public:
class mycomparsion {
public:
bool operator() (const pair<int, int> &left, const pair<int, int> &right) {
return left.second > right.second;
}
};
vector<int> topK(vector<int> nums, int k) {
// 1、使用无序字典,记录数组中每个元素出现的频率
unordered_map<int, int> umap;
for (int i = 0; i < nums.size(); i++) {
umap[nums[i]]++;
}
// 2、定义小顶堆,自定义的优先队列
priority_queue<pair<int, int>, vector<pair<int, int>>, mycomparsion> pri_que;
// 3、将无序字典中的元素 全部添加至自定义的优先队列中
for (auto iter = umap.begin(); iter != umap.end(); iter++) {
// 优先队列里面存储的元素是 键值对,并且是按值的大小排列,升序
pri_que.push(*iter);
// 只保留队列的后 k 个元素
if (pri_que.size() > k) {
pri_que.pop();
}
}
// 4、这时候优先队列中保存的元素就是最后的结果,我们将其的键值取出,即可
// 倒序取出,则先打印的是频率最高的元素,依次递减
vector<int> res(k); // 定义数组,k个元素,初始化全0
for (int i = k - 1; i >= 0; i--) {
res[i] = pri_que.top().first; // 取键值 -- 即取出的是 nums 数组中的元素
pri_que.pop();
}
return res;
}
};
int main() {
vector<int> nums{1, 1, 1, 2, 2, 3};
Solutional test;
vector<int> res;
res = test.topK(nums, 2);
for (int i = 0; i < res.size(); i++) {
cout << res[i] << " ";
}
}