【leetcode/优先队列】前k个高频元素(优先队列求前k个元素)

问题描述:

给定一个非空的整数数组,返回其中出现频率前 高的元素。

示例 1:

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

示例 2:

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

说明:

  • 你可以假设给定的 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
  • 你的算法的时间复杂度必须优于 O(n log n) , 是数组的大小。

基本思路:

用hashmap记录每个元素及其出现的次数。

用优先队列保存元素,然后求前k大的。

AC代码:

struct Pair{
  int a;
  int b;
  
  Pair(int _a, int _b) :
    a(_a), b(_b) {}
  
  bool operator<(const Pair &x) const {
    return b > x.b;
  }

  bool operator>(const Pair &y) const {
    return !(*this < y);
  }
};

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
      // 统计各个元素以及其对应的次数
      map<int, int> hashmap;
      for (int num : nums) {
        ++hashmap[num];
      }
      // 创建优先队列返回前k大的元素
      priority_queue<Pair, vector<Pair>, greater<Pair>> q;
      for (auto it = hashmap.begin(); it != hashmap.end(); ++it) {
        Pair p(it->first, it->second); 
        q.push(p);
      }
      vector<int> res;
      for (int i = 0; i < k; ++i) {
        res.push_back(q.top().a);
        q.pop();
      }
      return res;
    }
};

其它经验:

这道题竟然做了一下午,原因是对C++stl还不够熟悉,这里总结一下碰到的壁:

  1. priority_queue有接受两种模板,一种就是直接接受元素的类型,还有一种就是类似<int, vector<int>, greater<int>>这样的。
  2. 之前1提到的仅仅是针对priority_queue中的元素是int类型的情况。如果不是int类型,需要把int全部改为相关类型
  3. 我们algorithm中有些函数是可以使用lambda的,但是上面的greater不能使用lamdba,一是因为它必须要有一个模板,另外一个原因是greater其实是一个仿函数——它看上去是一个函数,其实是一个类
  4. 如果是自定义类型,完全可以通过在类内重载<和>, 然后在template中指定类型。(注意不管是this还是参数都得是const类型的)
  5. 我们的pair类型已经定义了各种比较操作符了。它是按照字典序来比较的。你无法通过非成员函数重载pair的比较。
  6. 最后,为了能够让pair类型能够按照我的定义来进行比较,我重新定义了一个新的类型,重载了<和>, 然后给模板传递我这个新定义的类型——见代码。
发布了137 篇原创文章 · 获赞 19 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43338695/article/details/102758327