力扣347:前K个高频元素

题目描述

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

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

# 例2
输入: nums = [1], k = 1
输出: [1]
解题思路

1、首先统计数组中每个元素出现的频率,可以使用 map
2、然后将元素和它对应的频率,以键值对的形式 添加到 优先队列中(小根堆),然后保留优先队列中的后 k 个元素
3、这时候优先队列中的 k 个元素就是要找的结果,要把队列中的键值对中的键倒序依次取出,然后保存到一个数组中,该数组就是最后的结果

代码

(C++)

#include 
#include 
#include 
#include 

using namespace std;

class Solutional {
public:
    class mycomparsion {
    public:
        bool operator() (const pair<int, int> &left, const pair<int, int> &right) {
            return left.second > right.second;
        } 
    };

    vector<int> topK(vector<int> nums, int k) {
        // 1、使用无序字典,记录数组中每个元素出现的频率
        unordered_map<int, int> umap;
        for (int i = 0; i < nums.size(); i++) {
            umap[nums[i]]++;
        }

        // 2、定义小顶堆,自定义的优先队列
        priority_queue<pair<int, int>, vector<pair<int, int>>, mycomparsion> pri_que;

        // 3、将无序字典中的元素 全部添加至自定义的优先队列中
        for (auto iter = umap.begin(); iter != umap.end(); iter++) {
            // 优先队列里面存储的元素是 键值对,并且是按值的大小排列,升序
            pri_que.push(*iter); 
            // 只保留队列的后 k 个元素
            if (pri_que.size() > k) {
                pri_que.pop();
            }
        }

        // 4、这时候优先队列中保存的元素就是最后的结果,我们将其的键值取出,即可
        //    倒序取出,则先打印的是频率最高的元素,依次递减
        vector<int> res(k); // 定义数组,k个元素,初始化全0
        for (int i = k - 1; i >= 0; i--) {
            res[i] = pri_que.top().first; // 取键值 -- 即取出的是 nums 数组中的元素
            pri_que.pop();
        }
        return res;
    }
};
int main() {
    vector<int> nums{1, 1, 1, 2, 2, 3};
    Solutional test;

    vector<int> res;
    res = test.topK(nums, 2);

    for (int i = 0; i < res.size(); i++) {
        cout << res[i] << " ";
    }

}

你可能感兴趣的:(编程笔面试题,leetcode,算法,C++,前K个高频元素)