当前位置: 首页 > news >正文

[LeetCode]day34 347.前k个高频元素

题目链接

题目描述

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

示例 1:

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

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

提示:

1 <= nums.length <= 105
k 的取值范围是 [1, 数组中不相同的元素的个数]
题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的

题解

思路

要求频率前k个高的元素的元素,很自然的就是先想到用map来收集每个元素出现的频率,然后对这些频率进行排序
所以这道题的难点就转化成了,怎么对频率进行排序?

这道题考察的是优先级队列的知识点
什么是优先级队列?
队列进出的顺序按照优先级,而不是进入的前后顺序
举个例子: 医院中处理病人不是按照病人来的顺序,而是根据病情的严重程度

我们需要找到频率前k高的元素,可以选择维护一个大小为k的堆,使堆里面的元素总是前k个大的。
那么要使用小顶堆还是大顶堆呢?
在小顶堆中,每次弹出的元素都是堆中最小的元素,堆中剩的是大的;大顶堆中,每次弹出的元素都是堆中最大的元素,堆中剩的是小的。
所以我们要选择小顶堆。

c++中恰好提供了这样一种队列,即priority_queue,队列内部的元素总是有序的,按照元素的权值进行排序。

所以我们可以设置一个大小为k的优先队列,遍历Map的过程中去维护这个队列。最后队列里面剩下的就是前k个出现频率最高的元素啦

代码书写

class MyComparison{
public:
    bool operator()(const pair<int,int>&m,const pair<int,int>&n){
            return m.second>n.second;
    }
};
class Solution {
public:

    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int,int>myMap;
        vector<int>re(k);
        for(int i =0;i<nums.size();i++){
            myMap[nums[i]]++;
        }
        priority_queue<pair<int,int>,vector<pair<int,int>>,MyComparison>q;
        for(auto it = myMap.begin();it!=myMap.end();it++){
            q.push(*it);
            if(q.size()>k){
                q.pop();
            }
        }
        for(int i=0;i<k;i++){
            re[i]=q.top().first;
            q.pop();
        }
        return re;

        
    }
};

可能会有像我一样的c++苦手看得眼花缭乱
我现在可以详细的解释一下。

  • 为什么采用unordered_map去收集每个元素的频率?
    因为我们不需要使键是有顺序的,并且unorder_map底层逻辑实现是哈希表,在平均情况下查找效率为O(1) 效率更高

  • priority_queue<pair<int,int>,vector<pair<int,int>>,MyComparison>q;是什么意思?
    第一个模版参数pair<int,int>代表这个优先级队列中存放的数据是pair<int,int>类型;
    第二个模版参数vector<pair<int,int>>代表这个队列的底层容器是vector<pair<int,int>>
    第三个模版参数MyComparison是一个自定义的类,为什么这里可以直接放一个类呢?
    priority_queque的声明如下:

template<
  class T,                           // 元素类型
  class Container = vector<T>,      // 底层容器(默认vector)
  class Compare = less<T>           // 比较器类型(默认less<T>)
> class priority_queue;

第三个参数 Compare 必须是一个类型,而不是函数或对象。
例如,less 和 greater 是STL中预定义的类型,它们内部重载了 operator(),因此可以生成函数对象(Functor)

  • 为什么要重新写一个类重载()呢?
    默认比较器会按 pair 的第一个元素的大小进行排序,而我们需要按第二个元素的大小进行排序,所以需要重写。

相关文章:

  • 使用开源OPUS-MT模型进行文本翻译(python)
  • android中activity1和activity2中接收定时消息
  • (C/S)架构、(B/S)架构
  • 粉尘环境下的智能生产革命 ——助力矿山行业实现高效自动化作业
  • 第九篇《行军篇》
  • 设计模式-单例模式
  • 【Javascript】计算器(Calculator)网页设计案例
  • NVIDIA Jetson Nano的国产替代,基于算能BM1684X+FPGA+AI算力盒子,支持deepseek边缘部署
  • 【Python项目】基于深度学习的电影评论情感分析系统
  • 机械臂路径规划方法综述(一)
  • 机器学习中的线性代数:奇异值分解 SVD
  • 汇编点亮LED
  • python文本处理openpyxl库安装与使用
  • 江科大51单片机笔记【9】DS1302时钟可调时钟(下)
  • 【五.LangChain技术与应用】【25.LangChain RAG检索器与完整案例:实战中的RAG应用】
  • Mac同时安装jdk8和jdk17,默认选择jdk8
  • 计算机组成与系统结构—袁春风阅读笔记(一)
  • 博查搜索API日调用量突破3000万次,达到Bing API的1/3。
  • 论文粗读——Isometric 3D Adversarial Examples in the Physical World
  • 【CSS】---- 纯 CSS 实现无限滚动轮播
  • LPR名副其实吗?如果有所偏离又该如何调整?
  • 河南发布高温橙警:郑州、洛阳等地最高气温将达40℃以上
  • 国际博物馆日|在辽宁省博物馆遇见敦煌
  • 河南一女子被医院强制带走治疗,官方通报:当值医生停职
  • 朱雀二号改进型遥二运载火箭发射成功
  • 篮球培训机构东方启明星被指停摆,家长称已登记未退费用超百万