• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

sm1le

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

lc.347 统计前K个高频元素

题目:给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
https://leetcode-cn.com/problems/top-k-frequent-elements/

解法一:优先队列+小根堆

//一种小根堆思路
class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        vector<int> res;
        unordered_map<int, int> m;  //map不用pair,前一个为值,后一个为频率
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q; //小根堆
        for(auto& i : nums)
        {
            m[i]++;
        }
        for(auto& i : m)
        {
            q.emplace(i.second, i.first);  //q.emplace(i.first, i.second)不对,不明白
            if(q.size() > k)
                q.pop();
        }
        while(!q.empty())
        {
            res.push_back(q.top().second);  //q.top().first不对,不明白
            q.pop();
        }
        return res;
    }
};

//另一种小根堆思路
class Solution{
public:
//自己定义大小比较方法
class Mycomparison{
public:
    bool operator()(const pair<int ,int>& a, const pair<int, int>& b)//重载
    {
        return a.second > b.second;
    }
};
    vector<int> topKFrequent(vector<int>& nums, int k) {
        vector<int> res;
        unordered_map<int, int> m;  //map不用pair
        priority_queue<pair<int, int>, vector<pair<int, int>>, Mycomparison> q;
        for(auto& i : nums)
        {
            m[i]++;
        }
        for(auto& i : m)
        {
            q.emplace(i);
            if(q.size() > k)
                q.pop();
        }
        while(!q.empty())
        {
            res.push_back(q.top().first);
            q.pop();
        }
        return res;
    }
};

解法二:遍历寻找

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        vector<int> res;
        unordered_map<int, int> m;  //map不用pair
        for(auto& i : nums)
        {
            m[i]++;
        }
        // vector<int> v;
        int maxfreq = 0;
        for(unordered_map<int, int>:: iterator it = m.begin(); it != m.end(); it++)
        {   
            if(it->second > maxfreq)
                maxfreq = it->second;
        }
        while(k)
        {
            for(auto& i : m)
            {
                if(i.second == maxfreq)
                {
                    res.push_back(i.first);
                    k--;
                }
            }                    
            maxfreq--;
        }
        return res;
    }
};

解法三:桶排序

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        vector<int> res;
        unordered_map<int, int> m;
        for(auto& i : nums)
        {
            m[i]++;
        }
        int maxfreq = 0;
        for(auto& i : m)
        {
            if(i.second > maxfreq)
                maxfreq = i.second;
        }
        vector<vector<int>> temp(maxfreq+1);//为什么不用数组:考虑到相同频率的元素,使用数组会覆盖。注意要+1以对齐下标和频率
        for(unordered_map<int, int>:: iterator it = m.begin(); it != m.end(); it++)
        {   
            temp[it->second].push_back(it->first);
        }
        for(int t = maxfreq; res.size() < k && t >= 0; t--)
        {
            for(auto& i : temp[t])
            {
                res.push_back(i);
            }
            if(res.size() == k)
                break;
        }
        return res;
    }
};

注意要点:
1.求频率相关考虑用map。
2.求前k个大考虑到用小根堆,前k小考虑用大根堆。这样做的好处是当插入元素比堆顶小/大时,可以直接扔掉,节约内存。
3.priority_queue默认为大根堆,可以自定义判断方式。

posted on 2022-04-13 12:43  sm1le  阅读(37)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3