滑动窗口机制

滑动窗口解决的问题:

【题目】

有一个整型数组arr和一个大小为w的窗口,从数组的最左边滑到最右边,且滑动过程中窗口大小可伸缩。

例如,数组为 [4, 3, 5, 4, 3, 3, 6, 7], 窗口滑动过程为:

[ 4   3   5 ] 4   3   3   6   7  

  4 [ 3   5 ] 4   3   3   6   7  

  4 [ 3   5   4 ] 3   3   6   7  

  4 [ 3   5   4   3 ] 3   6   7  

  4   3 [ 5   4   3 ] 3   6   7  

  4   3   5 [ 4   3 ] 3   6   7  

  4   3   5 [ 4   3   3 ] 6   7  

  4   3   5 [ 4   3   3   6 ] 7  

窗口中最大值依次为5, 5, 5, 5, 5, 4, 4, 6

设计一种数据结构,随时获得窗口中的最大值。

使用双端队列。

R右移:在队列尾加入元素,如果当前尾元素小于等于要加入的元素,弹出,直到队列空或当前尾元素大于要加入的元素。

L左移:检查队列头元素是否为L移动前所在元素,是则去掉头元素,否则return。

这样,双端队列从头到尾是当前窗口内数组从左到右依次过期,依次会有哪些数字成为最大值。

因此,R右移时:

如果加入的数字大于队尾元素,则:

1)加入的数字比队尾元素大

2)加入的数字比对尾元素晚过期

因此对尾元素没有存在的必要了,故弹出。

如果加入的数字等于队尾元素,则:

1)加入的数字与队尾元素等大

2)加入的数字比对尾元素晚过期

因此对尾元素没有存在的必要了,故弹出。

class Window{
public:
    int L;
    int R;
    vector<int> arr;
    deque<int> q;
    Window(vector<int>& nums){
        this -> L = -1;
        this -> R = -1;
        arr.assign(nums.begin(), nums.end());
    }
    void addNumFromRight(){
        if(R == arr.size() - 1){
            return;
        }
        R = R + 1;
        while(!q.empty() && arr[q.back()] <= arr[R]){
            q.pop_back();
        }
        q.push_back(R);
    }
    void removeNumFromLeft(){
        if(L >= R){
            return;
        }
        L++;
        if(q.front() == L){
            q.pop_front();
        }
    }
    int getMax(){
        if(!q.empty()){
            return arr[q.front()];
        }
        else{
            return INT_MIN;
        }
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芜湖高学成

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值