leetcode347。上位Kの高周波要素/ヒープ行

前に書く

この質問は、Tencentの質問にこれに基づいて最初のK個の低周波要素が追加されていることを除いて、Tencentの昨日の筆記テストの質問に似ています。

件名:347. Top K高周波要素

空でない整数配列を指定すると、その中の上位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個の高周波要素のセットは一意です。
    回答は任意の順序で返すことができます。

ソース:LeetCode
リンク:https ://leetcode-cn.com/problems/top-k-frequency-elements
著作権はLeetCode が所有しています商用転載については、正式な許可書にご連絡ください。非商用転載については、出典を明記してください。

基本的な考え方:2回マッピングする

  • Unordered_mapが初めて利用可能になりました:配列の要素がキーとして使用され、要素の数が値として使用されます
  • 2回目のマップの使用:キーで降順で並べ替え、要素の出現回数をキーとして使用し、要素を値として使用します。出現数が同じ要素が複数存在する可能性があるため、値はベクトルとして定義されます
class Solution {
    
    
public:
    
    vector<int> topKFrequent(vector<int>& nums, int k) {
    
    
        unordered_map<int, int> m;
        for(int i = 0; i < nums.size(); ++i){
    
    
            m[nums[i]]++;//值作为键
        }
        map<int, vector<int>, greater<int>> sm;//按照次数从大到小排
        for(auto temp : m){
    
    
            sm[temp.second].push_back(temp.first);//次数作为键
        }
        vector<int> res;
        int i = 0;
        while(i < k){
    
    
            for(auto temp : sm){
    
    
                for(int j = 0; j < temp.second.size() && i < k; ++j){
    
    
                    res.push_back(temp.second[j]);
                    ++i;
                }
                if(i >= k){
    
    
                    break;
                }
            }
        }
        return res;
    }
};


基本的な考え方2:マップ+優先キュー

  • Unordered_mapは要素数の統計を実現します
  • Priority_queueは、要素が回数順に配置されていることを認識し、カスタムタイプを必要とします
class Solution {
    
    
public:
    struct Node{
    
    //自定义类型,元素,元素出现的次数
        int val, cnt;
        Node(int a, int b): val(a), cnt(b){
    
    }
        bool operator<(const Node& temp)const{
    
    //注意该函数的定义
            return cnt > temp.cnt;
        }
    };
    vector<int> topKFrequent(vector<int>& nums, int k) {
    
    
        //统计数组中每一个元素出现的次数
        unordered_map<int, int> m;
        for(int i = 0; i < nums.size(); ++i){
    
    
            m[nums[i]]++;//值作为键
        }
        
        priority_queue<Node, vector<Node>> pq;
        for(auto temp : m){
    
    
            if(pq.size() < k){
    
    //队列中的元素不足k个时,直接放入队列
                pq.push(Node(temp.first, temp.second));
            }
            else{
    
    //超过k个时,需要确定当前的和队头的大小关系
                if(temp.second > pq.top().cnt){
    
    
                    pq.pop();
                    pq.push(Node(temp.first, temp.second));                    
                }
            }
        }
        
        vector<int> res;
        while(!pq.empty()){
    
    
            res.push_back(pq.top().val);
            pq.pop();
        }
        
        return res;
    }
};

おすすめ

転載: blog.csdn.net/qq_31672701/article/details/108451638