LeetCode 239.滑动窗口最大值
题目链接:239.滑动窗口最大值
踩坑:一开始觉得很简单,暴力求解即可,之后看了视频,学习了思路。因为先看了视频,所以没踩什么坑
思路:核心是怎么维护窗口内的数。固定窗口每次向后移动一格的行为很像队列,所以考虑使用队列这一数据结构。队列在push元素时,判断队尾元素是否大于新元素,若小于则pop队尾元素(所以需要双端队列),直到队尾大于等于新元素,再将新元素push,即保持队列中元素的递减(非严格)。这样可以将窗口内最大的元素保持在队首。pop时需要判断队首元素与窗口抛弃的元素是否相等,相等才pop,不相等说明在之前push阶段已经pop了。
代码:
class Solution {
public:
deque<int> q;
void pop(int a)
{
if(!q.empty() && q.front() == a) q.pop_front();
}
void push(int a)
{
while(!q.empty() && q.back() < a) q.pop_back();
q.push_back(a);
}
int getMax()
{
return q.front();
}
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> result;
for(int i = 0; i < k; i++)
{
push(nums[i]);
}
result.push_back(getMax());
for(int i = k; i < nums.size(); i++)
{
pop(nums[i-k]);
push(nums[i]);
result.push_back(getMax());
}
return result;
}
};
LeetCode 347.前K个高频元素
题目链接:347.前K个高频元素
踩坑:对大小堆的使用不熟悉(传入cmp需要构建结构体或类对()进行重载,且a>b是小顶堆,且cmp传参之前必须对底层存储结构传参)
思路:使用字典统计每个数字出现的频次。对字典中的键值对以值为基准降序排序。
- 使用vector将字典中的pair拿出来,使用sort函数搭配自定义cmp函数对vector排序。
- 使用优先级队列,只需要维护k的大小,对每个push进来的pair以second为基准比较。
代码:
class Solution {
public:
struct cmp
{
bool operator()(pair<int, int>& a, pair<int, int>& b)
{
return a.second > b.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> m;
vector<int> result;
for(int i = 0; i < nums.size(); i++)
{
m[nums[i]]++;
}
priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> q;
for(auto it = m.begin(); it != m.end(); it++)
{
q.push(*it);
if(q.size() > k) q.pop();
}
for(int i = 0; i < k; i++)
{
result.push_back(q.top().first);
q.pop();
}
return result;
}
};