代码解决
class Solution {
public:
// 自定义比较类,用于优先队列(小顶堆)
class mycomparison
{
public:
// 重载操作符,用于比较两个pair,基于pair的第二个值(频率)
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)
{
// 用于存储每个数字及其出现的频率
unordered_map<int,int> map;
for(int i = 0; i < nums.size(); i++)
{
map[nums[i]]++;
}
// 优先队列(小顶堆),用于维护频率最高的前k个元素
priority_queue<pair<int,int>, vector<pair<int,int>>, mycomparison> pri_map;
// 遍历频率表,将元素及其频率插入优先队列
for(auto it = map.begin(); it != map.end(); it++)
{
pri_map.push(*it);
// 如果优先队列的大小超过k,则弹出频率最小的元素
if(pri_map.size() > k)
{
pri_map.pop();
}
}
// 初始化结果向量,大小为k
vector<int> result(k);
// 从优先队列中提取前k个频率最高的元素
for(int i = k - 1; i >= 0; i--)
{
result[i] = pri_map.top().first;
pri_map.pop();
}
return result;
}
};
详细解释
-
自定义比较类:
mycomparison
类重载了operator()
,用来比较两个pair<int, int>
对象。比较基于pair
的第二个值(即频率)。这样可以使优先队列按频率从小到大排序(小顶堆)。
-
频率统计:
- 使用
unordered_map<int, int>
来统计nums
数组中每个数字出现的频率。键为数字,值为该数字出现的次数。
- 使用
-
优先队列:
- 定义优先队列
pri_map
,存储pair<int, int>
类型的数据,使用mycomparison
类进行比较,从而构建一个小顶堆。 - 遍历频率表,将每个数字及其频率插入优先队列。如果优先队列的大小超过
k
,就会移除频率最小的元素。这保证了优先队列中始终保存着频率最高的前k
个元素。
- 定义优先队列
-
构建结果向量:
- 初始化一个大小为
k
的结果向量result
。 - 从优先队列中提取前
k
个频率最高的元素,并按照从高到低的顺序存入结果向量中。
- 初始化一个大小为