单调队列入门 力扣239:滑动窗口最大值

[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/)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值