首页 > 其他分享 >力扣-前k个高频元素

力扣-前k个高频元素

时间:2023-07-30 13:33:28浏览次数:33  
标签:map nums 元素 力扣 vector 输出 pair 高频

1.问题描述

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

示例 1:

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

输出: [1,2]

示例 2:

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

输出: [1]

 

说明:

你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。

你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。

题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。

输出时,首先输出频率最高的元素,如果频率相同,则先输出元素值较大的元素。

2.输入说明

首先输入nums数组的长度n,

然后输入n个整数,以空格分隔。

最后输入k。

3.输出说明

首先输出频率最高的元素,如果频率相同,则先输出元素值较大的元素。

元素之间以空格分隔。

4.范例

输入:

8
1 1 1 2 2 3 3 4
3

输出:

1 3 2

5.思路

首先对每个元素出现的次数进行计算,并排序,使用字典map可映射每个元素出现的次数,元素为键,出现的次数为值;

其次因为要查找频率前K高的元素,因此可使用最小堆对出现次数进行排序。当当前元素的堆的个数超过k时,移除堆顶最小元素,将当前元素的出现次数插入堆中,遍历所有元素,计科获得堆中前k个高频元素所出现的次数。然而输出结果时需要输出前k高频的元素,且排序先输出最大,相同则先输出元素较大的值,因此在最小堆中使用

priority_queue< pair<int, int>, vector< pair<int, int> >, greater< pair<int, int> > > Q;  //构造最小堆

6.代码

#include <iostream>
#include <stdio.h>
#include <queue>
#include <vector>
#include <map>

using namespace std;class Solution {
public:
    vector<int> topKFrequent(vector<int> nums, int k)
    {
        // 使用字典,统计每个元素出现的次数,元素为键,元素出现的次数为值
        map<int, int> map;//注意map的用法
        for(int i:nums)//迭代遍历nums中元素并放入map中  ,注意 i用来代表nums中的每个元素
            map[i] ++;

        //优先级队列实现最小堆算法
        //1.优先队列没有front()函数与 back()函数,而只能通过top()函数来访问队首元素(也可以称为堆顶元素),也就是优先级最高的元素。
        //2.priority_queue又称为优先队列,其底层是用堆来进行实现的。在优先队列中,队首元素一定是当前队列中优先级最高的那一个。
        //第二个参数vector<>是用来承载底层数据结构堆(heap)的容器;
        //第三个参数less<>或者greater<>是对第一个参数的比较类,less<int>表示数字越大优先级越大,greater<int>表示数字越小,优先级越大。
        //3.关于vector< pair<int, int> >用法:类似于map,但map会对插入的元素按键自动排序,而且不允许键重复。vector的这种用法不会自动排序,而且允许重复。

        priority_queue< pair<int, int>, vector< pair<int, int> >, greater< pair<int, int> > > Q;
        //其中greater< pair<int,int> >会在first相等时比较second

        // 遍历map,维护一个大小为K的小顶堆
        for (auto it : map)//c++11以后用aoto遍历map
            if (Q.size() == k)
            { //队列满了,替换头元素,重新排序堆
                if (it.second > Q.top().first)//it指代map中元素,it.second指向频率;而Q.top().first指向堆顶元素的频率大小
                { //堆排
                    Q.pop();
                    Q.push(make_pair(it.second, it.first));//先根据元素出现频率排序,再根据元素大小排序
                }
            }
            else//小于K直接插入
                Q.push(make_pair(it.second, it.first));//这边插入时,pair<频率,元素值>
        vector<int> res;
        while (Q.size()) { //将优先队列中k个高频元素存入vector
            res.push_back(Q.top().second);//注意,这边second指向元素值
            Q.pop();
        }
        return vector<int>(res.rbegin(), res.rend());//反向迭代器 ,思考下为什么?解答:因为小顶堆是堆顶元素一个个弹出来的,
                                                     //也就是前K个中频率最低的那个元素,先进入到res中,所以最后的结果肯定要逆序输出!
    }

};
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int n,data,k;
    vector<int> nums;
    cin>>n;
    for(int i=0; i<n; i++)
    {
        cin>>data;
        nums.push_back(data);
    }
    cin>>k;
    vector<int> res=Solution().topKFrequent(nums,k);
    for(int i=0;i<res.size();i++)
    {
        if (i>0)
            cout<<" ";
        cout<<res[i];
    }
    return 0;
}

 

标签:map,nums,元素,力扣,vector,输出,pair,高频
From: https://www.cnblogs.com/ohye/p/17591331.html

相关文章

  • 力扣-任务调度器
    1.问题描述给定一个用字符数组表示的CPU需要执行的任务列表。其中包含使用大写的A-Z字母表示的26种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在1个单位时间内执行完。CPU在任何一个单位时间内都可以执行一个任务,或者在待命状态。然而,两个相同种类的......
  • 代码随想录算法训练营第三天|力扣203.移除链表元素、力扣707.设计链表、力扣206.反转
    链表定义:通过指针串联在一起的线性结构,每一个节点由两个部分组成:数据域和指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null,即为空指针。链表类型1.单链表2.双链表3.循环链表,即链表首尾相连,可以解决约瑟夫环问题链表的存储方式数组在内存中是连续分布的,......
  • 力扣---77. 组合
    给定两个整数 n 和 k,返回范围 [1,n] 中所有可能的 k 个数的组合。你可以按 任何顺序 返回答案。 示例1:输入:n=4,k=2输出:[[2,4],[3,4],[2,3],[1,2],[1,3],[1,4],]示例2:输入:n=1,k=1输出:[[1]] 提示:1<=n<=201<=k<=n......
  • 力扣---141. 环形链表
    给你一个链表的头节点 head ,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从0开始)。注意:pos 不作为参数进行传递 。仅仅是为了标......
  • 力扣-设置交集大小至少为2
    1.问题描述一个整数区间[a,b] (a<b)代表着从a到b的所有连续整数,包括a和b。给你一组整数区间intervals,请找到一个最小的集合S,使得S里的元素与区间intervals中的每一个整数区间都至少有2个元素相交。输出这个最小集合S的大小。示例1:输入:intervals=[[1......
  • Vue3之ref取render形式组件jsx元素节点
    [2023年7月28日22:16:06]ref取render方式组件节点一开始注意到组件setup和render一起使用的情况,好奇怎么通过ref取到render中jsx里的节点,一开始试了以下的尝试,结果是undefined的:import{defineComponent,ref,onMounted}from"vue";exportdefault......
  • 代码随想录算法训练营第三天| LeetCode 203.移除链表元素(同时也对整个单链表进行增删
    203.移除链表元素      题目链接/文章讲解/视频讲解::https://programmercarl.com/0203.%E7%A7%BB%E9%99%A4%E9%93%BE%E8%A1%A8%E5%85%83%E7%B4%A0.html    卡哥题目建议:本题最关键是要理解虚拟头结点的使用技巧,这个对链表题目很重要。   做题思路:   ......
  • 关于python中对np.array数据进行元素操作的讨论(形参与实参)
    最近发现了python中,如果将np.array(ndarray)类型的数据作为实参,传递给形参时,实参和形参会同时改变。例如下面的代码:importnumpyasnpnum=np.array([[1,2],[3,4]])deftest(a):a[0,1]=9print(a)test(num)print(num)输出结果:[[19][34]][[19][34]]会发......
  • 唯一元素的和
    给你一个整数数组 nums 。数组中唯一元素是那些只出现 恰好一次 的元素。请你返回nums 中唯一元素的和 。示例1:输入:nums=[1,2,3,2]输出:4解释:唯一元素为[1,3],和为4。示例2:输入:nums=[1,1,1,1,1]输出:0解释:没有唯一元素,和为0。示例3:输入:nums=[1,2......
  • 代码随想录算法训练营第一天| LeetCode 704. 二分查找、LeetCode 27. 移除元素
    704.二分查找    题目链接:https://leetcode.cn/problems/binary-search/   视频链接:https://www.bilibili.com/video/BV1fA4y1o715     文章讲解:https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html    卡哥的题目建......