347. 前 K 个高频元素

347. 前 K 个高频元素

题目描述:

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

示例 1:

输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]

示例 2:

输入: nums = [1], k = 1
输出: [1]
思路分析:

对我自己来说 , 首先我想到用一个map<int,int>,来记录 。first->是value , second->value元素出现的次数。

这样我们就收集到了整数数组每一个值出现的次数。那么我们处理收集到的数据 ?

采用优先级队列来进行数据处理 ,对于求前k个(对频率进行排序 -> 优先级队列)。

优先级队列底层是 ,堆是一个完全二叉树,当然你也可以不用知道它是如何实现的 ,只要会用就可以了。

首先肯定会想到大顶堆 (根节点是最大值),但是我们这里只需要维护前k个元素 ,

当元素的个数大于k时 ,要进行出队操作,此时如果我们出队 ,是不是将最大的数据移除出去了?

所以这里我们采用小顶堆(根节点是最小值)。

优先级队列的元素是一个键值对 (pair<int ,int>),和我们的map是对应的 。

在入队的时候 ,比较的是map<int,int>second ,出现次数少的排在前面。我们需要自定义一个比较函数(对()进行重写)。

struct my_compare{
     int operator()(const pair<int ,int>&a ,const pair<int ,int>&b){
         return a.second > b.second;
     }
};

当遍历完map中得所有元素,因为是小顶堆 ,前面的最小 ,后面的最大。

从后往前进行赋值 。

vector<int>ret( k ,0);  //定义一个vector ,大小是  k  讲所有值初始化为 0 
    while(!my_priority_queue.empty()){
         ret[--k]= my_priority_queue.top().first;   
         my_priority_queue.pop();
 }

完整代码实现:

class Solution {
public:
    struct my_compare{
        int operator()(const pair<int ,int>&a ,const pair<int ,int>&b){
            return a.second > b.second;
        }
    };
 
    vector<int> topKFrequent(vector<int>& nums, int k) {
        map<int ,int>index;   //first 是value  seconed 是数量
        //map ->记录每一个元素出现的个数
        for(int i = 0;i<nums.size() ;i++){
            index[nums[i]]+=1;
        }
        //优先队列 priority_queue   底层是二叉树
        priority_queue<pair<int ,int> ,vector<pair<int ,int >>,my_compare>my_priority_queue;
        for( auto temp: index){
            my_priority_queue.push(temp);
            if(my_priority_queue.size() >k ){
                my_priority_queue.pop();   //出队 ,我们只需要维护k个元素
            }
        }
        vector<int>ret( k ,0);
        while(!my_priority_queue.empty()){
            ret[--k]= my_priority_queue.top().first;   //获取对头元素 ,拿到键值对的 value
            my_priority_queue.pop();   //出队
        }
        return ret;
    }
};
  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零二年的冬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值