剑指offer:滑动窗口的最大值

题目描述

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

思路

用一个双端队列保存滑动窗口最大值,保证里面的元素顺序是从大到小的,如果当前入队元素小于队列前一个数值,就入队,因为一会窗口滑出可能这个小的就变成了最大值,
但是如果当前元素大于之前的元素,说明之前元素已经不是窗口内最大得了,就把前一个元素出队,一直到队空或者有元素大于当前元素,入队当前元素。这样队列里第一个元素永远都是最大的。
这里队列里保存的元素下标,而不是真正的数值,可以用下标来判断窗口大小。超出窗口大小就要滑出一部分数值。

code

class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        deque<int>dq;
        vector<int>res;
        for(unsigned int i=0;i<num.size();++i){
            while((!dq.empty())&&num[dq.back()]<=num[i])
                dq.pop_back();
            while((!dq.empty())&&i-dq.front()+1>size)//不可以用dq.size>size,滑动窗口可以删掉了中间结点
                dq.pop_front();
            dq.push_back(i);
            if(i>=size-1)
                res.push_back(num[dq.front()]);
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_33278461/article/details/80209857
今日推荐