题目链接
chatgpt写的代码,
首先这是个滑动窗口的问题,要用单调队列来解决,这个就是毋庸置疑的,就直接接受就行了
其次,不知道单调队列是啥,知道单调队列是啥了,又不知道单调队列该如何实现,单调队列用双端队列 deque实现,又不怎么清楚deque STL的相关操作.
明白了语法上怎么实现,现在又得发愁算法上如何实现,
如何保持单调队列呢----即如何让队列内的元素一直保持递减呢?
将入队元素和队尾元素比较,如果队尾元素小了,把队尾元素踢出去。
这也就说明了,咱单调队列的元素的实际个数,不一定非得是题里给的滑动窗口个数,有可能小
然后就是滑动窗口的大小得维持,就是怎么才能跟着往前走,就是每次遍历要先检查队头的元素,**咱这个队列元素存的是索引号!**是不是比i-k大,不大的话就是不符合队列大小的要求,就得队头元素出队。
之后就是入队,那么问题来了,为什么添加当前元素到队列(元素入队)要等移除不在窗口范围内的元素的索引和保持队列单调递减之后才添加
如果从编写代码的角度上就是,遍历到了当前的元素,那就得进行检验,而不是不管不顾就直接入队,得先改变队列,确保滑动窗口的大小和队列是单调队列之后再入队,
单调队列
不知道是啥,哈哈哈哈我也不知道
单调队列和优先队列是两种特殊的队列,它们在数据结构中扮演着重要的角色,尤其是在解决特定算法问题时。尽管它们的名字中都有“队列”,但它们的设计目的、操作方式和应用场景大相径庭。下面是单调队列和优先队列的主要区别:
单调队列(Monotonic Queue)
单调队列是一种特殊的队列,其元素按照单调递增或单调递减的顺序排列。这意味着队列中的元素是有序的,要么是从队头到队尾递增,要么是递减。单调队列主要用于解决滑动窗口类型的问题,如在一个滑动窗口中寻找最大值或最小值。
- 主要特点:
- 队列中元素单调递增或递减;
- 用于解决滑动窗口最值问题;
- 添加或移除元素时需要维持队列的单调性。
优先队列(Priority Queue)
优先队列是一种允许在插入过程中对元素进行排序的队列。在优先队列中,元素被赋予优先级,当访问队列时,拥有最高优先级的元素最先被移除。优先队列通常通过堆(Heap)数据结构来实现,以便高效地管理元素的优先级。
- 主要特点:
- 元素按优先级排序,最高优先级的元素最先被移除;
- 通常用堆(Heap)实现,以支持快速插入和删除操作;
- 用于需要元素优先级决定处理顺序的场景,如任务调度。
主要区别
- 目的和应用:单调队列主要用于处理滑动窗口内的最大值或最小值问题,而优先队列用于管理根据优先级排序的元素,适用于任务调度等场景。
- 元素排序:单调队列内的元素是根据单调递增或递减的规则排序的,而优先队列的元素排序是根据元素的优先级。
- 实现方式:单调队列可以通过双端队列(Deque)来实现,以便在两端添加或移除元素,而优先队列通常通过二叉堆等堆结构实现,以优化元素的插入和删除操作。
综上所述,尽管单调队列和优先队列都是队列的变体,但它们各自适用的场景、操作方式和实现机制有着根本的区别。选择使用哪一种队列结构取决于你面临的具体问题和需求。
#include <vector>
#include <deque>
using namespace std;class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {vector<int> result;deque<int> window; // 存储索引,而不是元素for (int i = 0; i < nums.size(); i++) {// 移除不在窗口范围内的元素的索引while (!window.empty() && window.front() <= i - k) {window.pop_front();}// 保持队列单调递减while (!window.empty() && nums[window.back()] < nums[i]) {window.pop_back();}// 添加当前元素索引到队列window.push_back(i);// 添加窗口的最大值到结果if (i >= k - 1) {result.push_back(nums[window.front()]);}}return result;}
};
自己重新写了一遍新犯的错误
#include <vector>
#include <deque>
using namespace std;class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {vector<int>result;deque<int>window;for(int i=0;i<nums.size();i++){while(!window.empty()&&window.front()<=i-k){window.pop_front();}while(!window.empty()&&nums[window.back()]<nums[i]){window.pop_back();}window.push_back(i);if(i>=k-1)result.push_back(nums[window.front()]);//如果只写这句话,那么就是从滑动窗口还没长到k那么大的时候就开始输出最大值了,所以必须有这个判断条件}return result;}
};