leetcode-master/problems/0239.滑动窗口最大值.md

60 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 题目地址
https://leetcode-cn.com/problems/sliding-window-maximum/
## 思路
这是使用单调队列的经典题目。
暴力方法遍历一遍的过程中每次从窗口中在找到最大的数值这样很明显是O(n * k)的算法。
有的同学可能会想用一个大顶堆也就是优先级队列来存放这个窗口里的k个数字这样就可以知道最大的最大值是多少了 但是问题是这个窗口是移动的,而大顶堆每次只能弹出最大值,我们无法移除其他数值,这样就造成大顶堆维护的不是滑动窗口里面的数值了。所以不能用大顶堆。
使用单调队列,即单调递减或单调递增的队列。 它不是一个独立的数据结构,需要使用其他数据结构来实现单调队列,例如: dequedeque是双向队列可以选择 从头部或者尾部pop同样也可以从头部或者尾部push。
不要以为实现的单调队列就是 对窗口里面的数进行排序,如果排序的话,那和优先级队列又有什么区别了呢。
详情看代码吧,已经简洁。
## C++代码
```
class Solution {
public:
class MyQueue { //单调队列(从大到小)
public:
deque<int> que; // 使用deque来实现单调队列
void pop(int value) {
if (!que.empty() && value == que.front()) {
que.pop_front();
}
}
void push(int value) {
while (!que.empty() && value > que.back()) {
que.pop_back();
}
que.push_back(value);
}
int front() {
return que.front();
}
};
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
MyQueue que;
vector<int> result;
for (int i = 0; i < k; i++) { // 先将前k的元素放进队列
que.push(nums[i]);
}
result.push_back(que.front()); // result 记录前k的元素的最大值
for (int i = k; i < nums.size(); i++) {
que.pop(nums[i - k]); // 模拟滑动窗口的移动
que.push(nums[i]); // 模拟滑动窗口的移动
result.push_back(que.front()); // 记录对应的最大值
}
return result;
}
};
```
> 更过算法干货文章持续更新可以微信搜索「代码随想录」第一时间围观关注后回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等就可以获得我多年整理的学习资料。