Leetcode
1.前k个高频元素
给定一个整数数组,返回出现频率前k高的元素。
思路:先用map统计各个数字出现频率。然后利用优先队列构建小顶堆(前k大构建小顶堆,前k小构建大顶堆),最后把最终的小顶堆输出。
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
map<int,int> cal;
using E = pair<int, int>;
priority_queue<E, vector<E>, greater<E>> minHeap;
for(auto n : nums)
++cal[n];
for(auto n : cal)
{
E p = make_pair(n.second, n.first);
if(minHeap.size()==k)
{
if(minHeap.top()>p)continue;
minHeap.pop();
}
minHeap.push(p);
}
int lenth = minHeap.size();
vector<int> res(lenth);
while(!minHeap.empty())
{
res[--lenth] = minHeap.top().second;
minHeap.pop();
}
return res;
}
};
2.前k个高频词汇
给定一串单词,返回出现频率前k高的单词。同1.,这里直接用大根堆,更暴力,全部建堆,效率肯定低。
class Solution {
public:
struct cmp
{
bool operator()(pair<string, int> a, pair<string, int> b)
{
if(a.second<b.second) return true;
else if(a.second>b.second) return false;
return a.first>b.first;
}
};
vector<string> topKFrequent(vector<string>& words, int k) {
using E = pair<string, int>;
map<string, int> wordsCntMap;
vector<string> res;
priority_queue<E, vector<E>, cmp> wordsCnt;
for(auto s:words)
++wordsCntMap[s];
for(auto s:wordsCntMap) wordsCnt.push(s);
for(int i = 0; i < k; i++)
{
res.push_back(wordsCnt.top().first);
wordsCnt.pop();
}
return res;
}
};
值得注意的是优先队列的排序,如果排序函数return a>b
,则从小到大排序,即小根堆,反之则从大到小排序,大根堆。排序函数必须要构建结构体,结构体最后要加分号。格式如下:
struct cmp
{
bool operator()(void a, void b)
{
}
}