• 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

  • 相关阅读:
    windows蓝屏错误小全
    大数据量下高并发同步的讲解(不看,保证你后悔)
    本地或者服务器同时启动2个或多个tomcat
    如何在同一系统里同时启动多个Tomcat
    Java配置----JDK开发环境搭建及环境变量配置
    Tomcat8内置jdk8运行环境发布web项目
    Tomcat 部署项目的三种方法
    Java Web(五) JSP详解(四大作用域九大内置对象等)
    Java 四大作用域总结
    JSP九大隐式对象
  • 原文地址:https://www.cnblogs.com/fresh-coder/p/14336823.html
Copyright © 2020-2023  润新知