滑动窗口的最大值

Posted lune-qiu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了滑动窗口的最大值相关的知识,希望对你有一定的参考价值。

题目描述

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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]}。
 
思路:
插入数字 滑动窗口 队列中的下标 最大值
2 2 0(2)  
3 2,3 1(3)  
4 2,3,4 2(4) 4
2 3,4,2 2(4),3(2) 5
6 4,2,6 4(6) 6
2 2,6,2 4(6),5(2) 6
5 6,2,5 4(6),6(5) 6
1 2,5,1 6(5),7(1) 5
每次加入一个新的数字,考察这个值有没有可能成为最大值。
考察的方法就是:看这个队列中有没有比这个小的值,如果有就去掉(去掉队尾元素),因为它是最后进入的,所以它一定会参与最大值评选,保留的时间也会更长。
但是如果队列中没有比这个值更小的,那么也要把它放进去,因为可能前面比它大的,会在滑动过程中删除,所以它可能成为最大值。
所以就是无论如何这个值都会进入队列。
由于滑动窗口,所以还要判断队列的头还在不在滑动窗口中,不在的话要去掉。(去掉队首元素)
这样就可以保证,队列首元素一定是滑动窗口中的最大值。
 
由于要对队列的首尾都进行操作,所以用到双向队列deque
添加到队首:que.push_front();
添加到队尾:que.push_back();
从队首删除:que.pop_front();
从队尾删除:que.pop_back();
我的代码:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        deque<int> que;//双向队列
        vector<int> res;
        int lenth = num.size();
        if(lenth == 0 || size > lenth ||size <= 0)
            return res;
        for(int i = 0; i < size;i++)
        {
            while(!que.empty() && num[i] >= num[que.back()])
                que.pop_back();//弹出比最后进入的元素小的数
            que.push_back(i);
        }
        res.push_back(num[que.front()]);
        for(int i = size;i < lenth;i++)
        {
            while(!que.empty() && num[i] >= num[que.back()])
                que.pop_back();//弹出比最后进入的元素小的数
            if(!que.empty() && que.front() <= i-size)
                que.pop_front();
            que.push_back(i);
            res.push_back(num[que.front()]);
        }
        return res;
    }

 

以上是关于滑动窗口的最大值的主要内容,如果未能解决你的问题,请参考以下文章

华为OD机试 -滑动窗口最大和(Java) | 机试题+算法思路+考点+代码解析 2023

Java 求解滑动窗口最大值

java刷题--239滑动窗口最大值

剑指 Offer 59 - I. 滑动窗口的最大值 c++/java详细题解

剑指 Offer 59 - I. 滑动窗口的最大值 c++/java详细题解

精选力扣500题 第69题 239. 滑动窗口最大值c++/java详细题解