问题描述:
给定一个非空的整数数组,返回其中出现频率前 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 是数组的大小。
基本思路:
用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还不够熟悉,这里总结一下碰到的壁:
- priority_queue有接受两种模板,一种就是直接接受元素的类型,还有一种就是类似<int, vector<int>, greater<int>>这样的。
- 之前1提到的仅仅是针对priority_queue中的元素是int类型的情况。如果不是int类型,需要把int全部改为相关类型。
- 我们algorithm中有些函数是可以使用lambda的,但是上面的greater不能使用lamdba,一是因为它必须要有一个模板,另外一个原因是greater其实是一个仿函数——它看上去是一个函数,其实是一个类。
- 如果是自定义类型,完全可以通过在类内重载<和>, 然后在template中指定类型。(注意不管是this还是参数都得是const类型的)
- 我们的pair类型已经定义了各种比较操作符了。它是按照字典序来比较的。你无法通过非成员函数重载pair的比较。
- 最后,为了能够让pair类型能够按照我的定义来进行比较,我重新定义了一个新的类型,重载了<和>, 然后给模板传递我这个新定义的类型——见代码。