LeetCode 347:哈希表+桶排序

本文介绍了一种使用哈希表结合桶排序的方法来找出数组中出现频率最高的前k个元素。该方法通过构建哈希表记录每个元素出现的次数,并利用桶排序对元素按出现频率进行排序,最终返回频率最高的前k个元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

给定一个非空的整数数组,返回其中出现频率前k高的元素。
例如:
给定数组[1,1,1,2,2,3],其中k=2,则返回[1,2]

注意:
(1)可以假设给定的k总是合理的,1<=<=数组中不相同的元素个数
(2)算法的时间复杂度必须优于o(nlogn),n是数组的大小

解题思路:哈希表+桶排序
(1)定义一个哈希表,然后数值元素作为哈希表的关键字first,哈希表的值作为关键字的个数,进行遍历;
(2)将哈希表的关键字存在一个数组中,然后根据哈希表的值进行比较排序,按照降序排序;
(3)对数组遍历前k个位置便得到相关的元素;

 方法一:


/*哈希表+桶排序*/
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>

using namespace std;
static int x=[](){
    ios::sync_with_stdio(false);
    cin.tie(0);
    return 0;
}();  //加快输入输出操作

class Solution{
 public:
    
    vector<int> TopFrequency(vector<int>& nums,int k){
        
        unordered_map<int,int> map;
        for(auto& i:nums)  //&引用数组本身,不需要拷贝
           ++map[i];//i代表数组元素,map[i]是元素的个数,进行加1操作
        
        for(auto& j:map)
            bucket.push_back(j.first); //关键字存入桶中
        
        /*
        这样表达也可以
        for(auto j=map.begin();j!=map.end();j++)
            bucket.push_back(j->first);   
        */      
        //sort(begin,end,compare),三个参数,compare是bool型
        sort(bucket.begin(),bucket.end(),[&map](int a,int b){return map[a]>map[b];});//按照降序排序 
        return vector<int>(bucket.begin(),bucket.begin()+k);//输出前k个高频数组
    }

private:
     vector<int> bucket;

};

int main(int argc,char* argv[]){
    int test[]={1,3,4,4,5,6,9,3,3};
    vector<int> nums(test,test+9);
    for(auto &member:Solution().TopFrequency(nums,2))
         cout<<member<<"  ";
    cout<<endl;
    return 0;
}

方法二: 

/*哈希表+桶排序*/
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>

using namespace std;
static int x=[](){
    ios::sync_with_stdio(false);
    cin.tie(0);
    return 0;
}();  //加快输入输出操作

bool compare(const pair<int,int>& a,const pair<int,int>& b){
        return a.second>b.second;
}

class Solution{
 public:
    vector<int> topfrequent(vector<int>& nums,int k){
        map<int,int> elements;
        for(int i=0;i<nums.size();i++)
            elements[nums[i]]++;//nums代表数组元素,elemets[i]是元素的个数,进行加1操作
        
        for(auto it=elements.begin();it!=elements.end();it++)
            butkets.push_back(pair<int,int>(it->first,it->second));

        sort(butkets.begin(),butkets.end(),compare);//按照降序排序,自定义compare,传入pair

        vector<int> result;//用于存储结果
        for(int i=0;i<k;i++)
             result.push_back(butkets[i].first);

        return result; 

    }
    
private:
     vector<pair<int,int>> butkets;//关键字存入桶中,第一个值为元素,第二个值为元素数量

};

int main(int argc,char* argv[]){
    int test[]={1,3,4,4,5,6,9,3,3};
    vector<int> nums(test,test+9);
    for(auto &member:Solution().topfrequent(nums,2))
         cout<<member<<"  ";
    cout<<endl;
    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路上的追梦人

您的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值