思路: 这个题目相当于用了最小堆的优先队列,但是我们以往优先队列只能传1个元素。在这里我们传送了pair~~而且我们pair的比较对象在second中,所以我们要创建一个自己的比较程序。cmp 注意到这个cmp函数的return意味着,m是新来的或者后面的 n是前面的,新来的如果大 那就交换,也就是return是true的时候就交换 往前面交换,也就是从大到小。
注意到最小堆应该是从小到达排序,应该是小于号,但是注意到这边就是反的 !!!
class Solution {
public:
static bool cmp(pair<int, int>& m, pair<int, int>& n) {
return m.second > n.second;
}
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> occurrences;
for (auto& v : nums) {
occurrences[v]++;
}
// pair 的第一个元素代表数组的值,第二个元素代表了该值出现的次数
priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(&cmp)> q(cmp);
for (auto& [num, count] : occurrences) {
if (q.size() == k) {
if (q.top().second < count) {
q.pop();
q.emplace(num, count);
}
} else {
q.emplace(num, count);
}
}
vector<int> ret;
while (!q.empty()) {
ret.emplace_back(q.top().first);
q.pop();
}
return ret;
}
};
第二种算法很巧妙,对哈希表的运用要比较熟练,有时候取哈希表元素都要用auto,其实在这里我们可以用哈希表的.begin() 等来表示哈希表中某一个最先地址的元素,虽然我不知道他是什么,但是肯定是某个元素~~ 每次取哈希表中的一个元素,和其他元素比值大小,保留最大的,每次选出当前排名最好的。然后从哈希表中抹除这个元素。继续排名K次。遍历哈希表每个元素的方式为了和for类似,这里采用了.begin()和 .end();
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int> mp;
for(int i=0;i<nums.size();i++){
mp[nums[i]]++;
}
vector<int> ret;
for(int i=0;i<k;i++){
auto its=mp.begin();
for(auto it=mp.begin();it!=mp.end();it++){
if(its->second < it->second){
its=it;
}
}
ret.push_back(its->first);
mp.erase(its);
}
return ret;
}
};
另外,还有一种方法是快速排序,详情看Leetcode解答,当复习到集中排序的方法时再回顾把!