第12天-代码随想录刷题训练-第五章 栈和队列3 - ● 239. 滑动窗口最大值 ● 347.前 K 个高频元素
今天主要是队列的应用
1. 滑动窗口最大值 (困难-单调队列)
LeetCode 原题
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值
- 思路
- 暴力方法,每次遍历窗口内的数据,遍历(n-k 1)次,时间复杂度为 k*n
- 滑动窗口的过程很像是一个队列, 每次遍历一个元素都要 pop一个元素, push一个元素, 最后再getMax
- 因此这是一个优先级队列,C 中相当于实现一个 大顶堆, 头部元素是最大值, 底层由二叉树实现,但是顶部元素是最大值,每次都是pop最大值
- 综上本文要实现的应该是一个单调队列: 队列中只存储当前最大值(作为队列头元素)和最大值之后的元素,最大值之前的元素全部pop掉,对本题的求窗口内最大值并没有帮助
- 考虑到本题需要在两端对队列进行操作,因此使用deque数据结构
- pop_q(val): 判断deque是否为空, front()与val是否相等,是则pop()
- push_q(val): push的时候,先判断是否为空与back()的元素比大小,如果一直大于back()的元素则一直pop_back()
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> maxResult;
int max;
for(int i=0; i<k; i ){
push_back(nums[i]);
}
max = getMaxVal();
maxResult.push_back(max);
for(int i=k; i<nums.size(); i ){
pop_front(nums[i-k]);
push_back(nums[i]);
max = getMaxVal();
maxResult.push_back(max);
}
return maxResult;
}
void push_back(int val){
while(!dq.empty() && val>dq.back()){
dq.pop_back();
}
dq.push_back(val);
}
void pop_front(int val){
if(!dq.empty() && dq.front()==val){
dq.pop_front();
}
}
int getMaxVal(){
int result;
if(!dq.empty()){
result = dq.front();
}
return result;
}
private:
deque<int> dq;
};
2.前 K 个高频元素 (大顶堆 和 小顶堆)
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
- 思路
- 遍历一遍数组,使用map存储 key元素值 和val出现的次数
- 使用大顶堆还是小顶堆, 由于顶堆这个数据结构每次都弹出顶部元素,如果使用val排序的大顶堆,每次会将出现频率大的值都给弹出来,因此应该使用小顶堆
- C 中的 大顶堆/小顶堆 数据结构 priority_queue
- 优先级队列中存储的是 pair<k, v> 值, 然后自定义Compare函数来定义小顶堆
- 基础
- 树形结构使用迭代器遍历?
- priority_queue 的Compare函数
- priority_queue要自定义Compare函数就需要定义第二个参数,底层实现的容器 vector deque list
- 优先级队列的 Compare函数 left > right 是小顶堆, left < right 是大顶堆
- 使用lambda函数的时候需要注意 使用方式
class Solution {
public:
class mycomparison{
public:
bool operator()(const pair<int, int>& lhs, const pair<int, int>& rhs){
return lhs.second > rhs.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
// 使用优先级队列实现 小顶堆
// map存储元素的值和出现的次数
unordered_map<int, int> m;
for(auto num : nums){
m[num] ;
}
// priority_queue<pair<int, int>, vector<pair<int, int>>, mycomparison> pq;
auto compar = [](pair<int, int>& lhs, pair<int, int>& rhs){ return lhs.second > rhs.second;};
priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(compar)> pq(compar);
// priority_queue 有size()函数
for(unordered_map<int, int>::iterator im = m.begin(); im != m.end(); im ){
pq.push(*im);
if(pq.size() > k){
pq.pop();
}
}
vector<int> result;
// 不能使用迭代器访问树结构
for(int i=0; i<k; i ){
int num = pq.top().first;
pq.pop();
result.push_back(num);
}
return result;
}
};
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgghkaf
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13