使用优先队列解决LeetCode347前K个高频元素

使用优先队列解决LeetCode347前K个高频元素

优先队列也是队列,不同于普通队列是队头队尾元素进行出队和入队的操作,优先队列是寻找队列中的最大值或者最小值来进行操作。

优先队列的底层实现是堆。对于堆要熟悉到白板编程的程度。

C++中的优秀队列容器是priority_queue.

#include<iostream>
#include<queue>
#include<ctime>

using namespace std;

bool myCmp(int a,int b){
    return a%10<b%10;			//比较两个数的个位数,个位数大的排在前面
}
int main(){
    srand(time(NULL));   		//随机数种子
    
    priority_queue<int> pq;		//以最大堆为底层的优先队列
    
    for(int i=0;i<10;i++){
        int num = rand()%100;
        pq.push(num);
        cout<<"insert"<<num<<"in priority queue."<<endl;
    }
    while(!pq.empty()){
        cout<<pq.top()<<" ";
        pq.pop();
	}
    cout<<endl<<endl;
    
    priority_queue<int,vector<int>,greater<int>> pq2;  //以最小堆为底层的优先队列
     
    for(int i=0;i<10;i++){
        int num = rand()%100;
        pq2.push(num);
        cout<<"insert"<<num<<"in priority queue."<<endl;
    }
    while(!pq2.empty()){
        cout<<pq2.top()<<" ";
        pq2.pop();
	}
    
    priority_queue<int,vector<int>,function<bool(int,int)>> pq3(myCmp); //自定义比较函数
    
    for(int i=0;i<10;i++){
        int num = rand()%100;
        pq3.push(num);
        cout<<"insert"<<num<<"in priority queue."<<endl;
    }
    while(!pq3.empty()){
        cout<<pq3.top()<<" ";
        pq3.pop();
	}
    
    return 0;
    
}

leetcode347

在这里插入图片描述

算法思路:维护一个含有K个元素的优先队列,如果遍历到的元素比队列中最小频率元素的频率高,则取出队列中最小频率的元素,将新元素入队。最终,队列中剩下的,就是前k个出现频率最高的元素。此时算法的时间复杂度是O(nlogk)

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {

        //统计每个元素出现的频率
        unordered_map<int,int> freq;
        for(int i=0;i<nums.size();i++){
            freq[nums[i]]++;
        }
        //扫描数组,维护当前出现频率最高的k个元素
        //优先队列中,按照频率排序,所以数据对是(频率,元素)的形式
        priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>> > pq;
        for(unordered_map<int,int>::iterator iter=freq.begin();iter!=freq.end();iter++){
            if(pq.size()==k){
                //unordered_map中频率在second,优先队列中频率在first
                if(iter->second > pq.top().first){
                    pq.pop();
                    pq.push(make_pair(iter->second,iter->first));
                }
            }
            else
                pq.push(make_pair(iter->second,iter->first));
        }
        vector<int> res;
        while(!pq.empty()){
            res.push_back(pq.top().second);
            pq.pop();
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值