[239. 滑动窗口最大值](https://leetcode.cn/problems/sliding-window-maximum/)
如何用O(n)的时间复杂度求数组中所有长度为k的子数组的元素最大值
例子:[2,1,4,2,3,2] k=3
遍历数组,窗口长度>=3时才开始记录答案,[2,1,4]中显然最大值是4,若窗口继续向右移动,最大值也不可能取到前面的2和1,因为后面要包含2和1,就必须包含4,所以如果要维护滑动数组的最大值,可以直接忽略前面比4小的2和1;窗口右移,变为[1,4,2]此时2后面有可能成为最大值,所以要加入维护的队列中,继续右移窗口为[4,2,3],同理可以把3前面的2从维护队列去掉,因为2之后不可能再成为最大值了。
可以发现这样维护出来的队列是单调递减的,因为每加入一个可能成为最大值的元素,就可以把前面比它小的元素删除。除此之外,滑动窗口向右移的过程中当前队列中的最大值会移出窗口,所以要判断当前队列中最大值和当前遍历到的位置的距离,若超出窗口的长度,则应该把队列中第一个元素踢出(最大元素),因为要在队列两端都删除,所以用双端队列来维护
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
deque<int> q; //记录元素下标
vector<int> ans;
for(int i=0;i<nums.size();i++){
//窗口加入nums[i],加入前把前面比它小的删除
while(!q.empty()&&nums[q.back()]<nums[i]){
q.pop_back();
}
q.push_back(i);
//加入一个元素后,加入元素与队列最大元素距离大于k的话,说明队首最大元素应该被踢出窗口
if(i-q[0]+1>k){
q.pop_front();
}
if(i>=k-1){ //当满足窗口大小时才开始记录答案
ans.push_back(nums[q.front()]);
}
}
return ans;
}
[LCR 184. 设计自助结算系统](https://leetcode.cn/problems/dui-lie-de-zui-da-zhi-lcof/)
[2398. 预算内的最多机器人数目](https://leetcode.cn/problems/maximum-number-of-robots-within-budget/)
[绝对差不超过限制的最长连续子数组](https://leetcode.cn/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit/)