leetcode347. Top K high-frequency elements/heap row

Write in front

This question is similar to Tencent's written test question last night, except that Tencent's question adds the first K low-frequency elements on this basis. It seems that more questions are still beneficial.

Subject: 347. Top K high-frequency elements

Given a non-empty integer array, return the top k elements in it.

Example 1:

输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]

Example 2:

输入: nums = [1], k = 1
输出: [1] 

prompt:

  • You can assume that the given k is always reasonable, and 1 ≤ k ≤ the number of different elements in the array.
  • The time complexity of your algorithm must be better than O(n log n), where n is the size of the array.
  • The question data guarantees the unique answer, in other words, the set of the first k high-frequency elements in the array is unique.
    You can return the answers in any order.

Source: LeetCode
Link: https://leetcode-cn.com/problems/top-k-frequent-elements The
copyright is owned by LeetCode . For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.

Basic idea: map twice

  • Unordered_map is available for the first time: the elements of the array are used as keys and the number of elements is used as the value
  • Use map for the second time: be sure to sort by key in descending order, use the number of occurrences of the element as the key, and use the element as the value. Since there may be multiple elements with the same number of occurrences, the value is defined as a vector
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;
    }
};


Basic idea 2: map + priority queue

  • Unordered_map realizes the statistics of the number of elements
  • Priority_queue realizes the elements are arranged in order of the number of times, and requires a custom type
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;
    }
};

Guess you like

Origin blog.csdn.net/qq_31672701/article/details/108451638