239. 滑动窗口最大值 - leetcode刷题(C++)

一、题目

239. 滑动窗口最大值
剑指 Offer 59 - I. 滑动窗口的最大值

二、分析

采用双端单调递减队列,保证队列中从大到小的顺序,为了方便,队列中只存储数组下标。

  1. 当队头元素超出窗口,则队友元素出队。
  2. 当新元素比队尾元素大,循环出队,保持队列的单调减。
nums = [1,3,-1,-3,5,3,6,7], k = 3
滑动窗口的位置                  队列
---------------               -----
[1  3  -1] -3  5  3  6  7       3 -1
 1 [3  -1  -3] 5  3  6  7       3 -1 -3
 1  3 [-1  -3  5] 3  6  7       5          //-3 -1 3依次从队尾出队,保持单调减
 1  3  -1 [-3  5  3] 6  7       5 3
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7

如果,是下面这个例子:
nums = [1,3,-1,-3,-4,3,6,7], k = 3
滑动窗口的位置                  队列
---------------               -----
[1  3  -1] -3  -4  3  6  7       3 -1
 1 [3  -1  -3] -4  3  6  7       3 -1 -3
 1  3 [-1  -3  -4] 3  6  7       -1 -3 -4      //由于3已经超出窗口,从队头出队
 1  3  -1 [-3  -4  3] 6  7       3
 1  3  -1  -3 [-4  3  6] 7       6
 1  3  -1  -3  -4 [3  6  7]      7

三、代码

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        int n(nums.size());
        vector<int> res;
        if(n == 0) return res;
        if(k == 1) return nums;
        int maxFirst = INT_MIN;
        int maxIndex = 0;

        deque<int> sw; //记录下标
        sw.push_back(0);
        for(int i = 1; i < n; i ++){
        	//判断队头有没有超出窗口
            if(!sw.empty() && sw.front() <= i-k) sw.pop_front();
            // 循环地从队尾删除元素,保证单调减
            while(!sw.empty() && nums[sw.back()] < nums[i]){
                sw.pop_back();
            }
            sw.push_back(i);
            //开始记录窗口最大值,即队头元素
            if(i >= k-1){
                res.push_back(nums[sw.front()]);
            }
        }
        return res;
    }
};

执行用时:368 ms, 在所有 C++ 提交中击败了67.60%的用户
内存消耗:128.7 MB, 在所有 C++ 提交中击败了24.50%的用户

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值