[LeetCode]347. Top K Frequent Elements

最大堆

Posted by JinFei on September 18, 2021

题目描述

Given a non-empty array of integers, return the k most frequent elements.

Example1:

Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]

Example2:

Input: nums = [1], k = 1
Output: [1]

Note:

  1. You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
  2. Your algorithm’s time complexity must be better than O(n log n), where n is the array’s size.

最大堆解题思路

  • 让统计前k个高频的数字,那么对于这类的统计数字的问题,首先应该考虑用 HashMap 来做,建立数字和其出现次数的映射,unordered_map实现
  • 然后再按照出现次数进行排序。可以用堆排序来做,使用一个最大堆来按照映射次数从大到小排列,在 C++ 中使用 priority_queue 来实现,默认是最大堆,

C++代码

class Solution {
public:
    static bool cmp(const pair<int, int>& mmap1, const pair<int, int >& mmap2){
        return mmap1.second > mmap2.second;
    }
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int, int> mmap;
        for(int i = 0 ; i < nums.size(); i++){
            mmap[nums[i]]++;
        }
        priority_queue<pair<int, int>> q;               // 元素也是一个一个的pair
        for(auto &i : mmap){
            q.push(make_pair(i.second, i.first));       // 这样就按照第二个关键字进行排序了
        }
        vector<int> res;
        for(int i = 0; i < k; i++){
            res.push_back(q.top().second);              // q.top() 取到按照second进行排序的最大元素
            q.pop();        // 记得执行pop操作
        }
        
        return res;
    }
};

重新cmp函数解题思路

  • 使用unordered_map解题思路
    1. 首先 unordered_map, map这种键值对容器是不支持直接sort的,需要将其pair元素push到序列化容器中
    2. 在C++里类重写cmp函数,这个cmp函数应该是静态的 即 static bool cmp
    3. cmp的参数也要注意,应该是 const pair<int, int>& a, const pair<int, int>& b 这个形参只能是pair,不能是unordered_map
    4. 取值的时候,有两种方法,iter -> second / (*iter).second 等等
    5. 如果取到的元素是pair本身,那么直接用 . 运算符即可取到元素

C++代码

class Solution {
public:
    static bool cmp(const pair<int, int>& mmap1, const pair<int, int >& mmap2){
        return mmap1.second > mmap2.second;
    }
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int, int> mmap;
        for(int i = 0 ; i < nums.size(); i++){
            mmap[nums[i]]++;
        }
        
        // sort(mmap.begin(), mmap.end(), cmp);    // map,unordered_map中的元素是以pair类存在,不支持排序
        vector<pair<int, int>> v_mmap;
        for(auto &i : mmap){
            v_mmap.push_back(i);           // 将其转换成vector容器,下面进行排序
        }
        stable_sort(v_mmap.begin(), v_mmap.end(), cmp);
        vector<int> res;
        for(int i = 0; i < k; i++){
            res.push_back(v_mmap[i].first); ** // v_mmap 其实是具体的pair,如果是取到具体的pair的话,用.运算符,如果使用迭代器来遍历元素额话,则使用 -> 运算符 **
        }
        return res;
    }
};

C++代码

class Solution {
public:
    static bool cmp(pair<int, int> &p1, pair<int, int>& p2){
        return p1.second > p2.second;
    }
    vector<int> topKFrequent(vector<int>& nums, int k) {
        if(k > nums.size()){
            return {};
        }
        vector<int> res;
        unordered_map<int, int> mmap;
        for(auto& i : nums){
            mmap[i]++;
        }
        vector<pair<int ,int>> vec(mmap.begin(), mmap.end());
        sort(vec.begin(), vec.end(), cmp);
        for(int i = 0; i < k; i++){
            res.push_back(vec[i].first);
        }
        return res;
    }
};