zoukankan      html  css  js  c++  java
  • 347. 前 K 个高频元素

    题目

    给定一个非空的整数数组,返回其中出现频率前 高的元素。

    分析

    1.统计每个数字出现的频率,用map哈希即可

    2.找 Top K 问题,用优先级队列

    关键是用小根堆还是大根堆,其实我的第一反应是建立大根堆,最后取k大根堆的头K个即可,这样时间复杂度是O(nlogn).

    如果采用小根堆,每次维护K个元素的小根堆,这样每次排序的时间复杂度是 logK,总体时间复杂度就降到了O(nlogk)。具体来说就是,每次弹出小根堆根结点,插入元素。这样最后剩下的就是最大的K个元素,最后还需要将这个优先级队列弹出后再逆置。

    代码

    自己一开始建立大根堆 O(nlogn).

     1 class Solution {
     2 public:
     3     //大根堆
     4     class myComp{
     5     public:
     6         bool operator()(pair<int,int>p1,pair<int,int>p2){
     7         return p1.second < p2.second;
     8         }
     9     };
    10 
    11     vector<int> topKFrequent(vector<int>& nums, int k) {
    12         //统计每个数字出现的频率,用map
    13         unordered_map<int,int>mp;
    14         for(int i = 0;i < nums.size();i++){
    15             mp[nums[i]]++;
    16         }
    17 
    18         priority_queue<pair<int,int>,vector<pair<int,int>>,myComp> pri_que;
    19         for (auto it = mp.begin(); it != mp.end(); it++) {
    20             pri_que.push(*it);
    21         }
    22         vector<int>res;
    23         for(int i = 0;i < k;i++){
    24             res.push_back(pri_que.top().first);
    25             pri_que.pop();
    26         }
    27         return res;
    28     }
    29 };

    建立个数为 K 的小根堆O(nlogk)

    class Solution {
    public:
        class myComp{
        public:
                bool operator()(const pair<int,int> &p1,const pair<int,int> &p2){
                    return p1.second > p2.second;
                }
        };
        
        vector<int> topKFrequent(vector<int>& nums, int k) {
            //1.用map哈希存每个元素出现的频率
            unordered_map<int,int>mp;
            for(int i = 0;i < nums.size();i++){
                mp[nums[i]]++;
            }
            //2.建立小根堆
            priority_queue<pair<int,int>, vector<pair<int,int>>,myComp>pri_que;
    
            for(auto it = mp.begin();it != mp.end();it++){
                pri_que.push(*it);
                if(pri_que.size() > k) pri_que.pop();
            }
            //3.将结果存入res,再逆置
            vector<int>res;
            for(int i = 0;i < k;i++){
                res.push_back(pri_que.top().first);
                pri_que.pop();
            }
            reverse(res.begin(),res.end());
            return res;
        }
    };

    总结:

    1. top K 问题用优先级队列, 如果求前 K个最大值,用小根堆。若求前K个最小值,用大根堆。

    2. 大根堆的实现,自己写比较类时,要注意 left < right 是 大根堆,这一点与sort中的自定义比较函数正好相反

    3.相关优先级队列的知识 https://blog.csdn.net/weixin_36888577/article/details/79937886

  • 相关阅读:
    python压平嵌套列表
    利用Python通过频谱分析和KNN完成iphone拨号的语音识别
    教你用Python Jupyter Notebook 制作代码分享 PPT
    windows10远程桌面连接身份验证错误:函数不受支持,这可能是由于 CredSSP 加密 Oracle 修正
    常用Linux命令
    利用uWSGI和nginx进行服务器部署
    阿里云ECS Ubuntu16.0 安装 uwsgi 失败解决方案
    阿里云上安装pip3(Ubuntu)
    基于python的快速傅里叶变换FFT(二)
    基于Python的频谱分析(一)
  • 原文地址:https://www.cnblogs.com/fresh-coder/p/14336823.html
Copyright © 2011-2022 走看看