zoukankan      html  css  js  c++  java
  • 牛客网-滑动窗口-(单调队列)

    链接:https://ac.nowcoder.com/acm/problem/50528
    来源:牛客网

    题目描述

    给一个长度为N(<=1e6)的数组,一个长为K的滑动窗体从最左端移至最右端,你只能看到窗口中的K个数,每次窗体向右移动一位,如下图:
    你的任务是找出窗体在各个位置时的最大值和最小值。

    输入描述:

    第1行:两个整数N和K;
    第2行:N个整数,表示数组的N个元素(≤2e9);

    输出描述:

    第一行为滑动窗口从左向右移动到每个位置时的最小值,每个数之间用一个空格分开;
    第二行为滑动窗口从左向右移动到每个位置时的最大值,每个数之间用一个空格分开。
    示例1

    输入

    8 3
    1 3 -1 -3 5 3 6 7

    输出

    -1 -3 -3 -3 3 3
    3 3 5 5 6 7

    思路:

    区间性问题,首先要有一个l和r指示区间左右两边。

    开一个dq数组,存元素的下标,再通过引用原数组获得值去比较,存下标的好处是可以指示出区间长度。

    举例取区间最小值的,每遍历一个a[i],把队列中比它小的弄掉,让当前这个更小的当头,形成单调队列,l始终指示区间范围最小的,队头用r指示。详看代码。

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<string>
    #include<map>
    #include<queue>
    #include<stack>
    #include<set>
    #include<ctime>
    #define ll long long
    #define inf 0x3f3f3f3f ///填充无限小-0x7f
    
    int n,k;
    int a[1000086];
    int dq[1000086];///用来存储a[i]的下标,数组a通过下标获取值,区间范围[ i-k,i ], i-k<=l<=r<=i
    
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
    
        int l=0,r=0;
        dq[0]=1;
        r=1;
        for(int i=2;i<=n;i++)
        {
            while(r>l && a[ dq[r-1] ]>a[i])///要找最小值,那么如果队列中的数 比 a[i]大,那就不要了,通过r--弹出后覆盖
                r--;
            dq[r++]=i;
            if(dq[l]<=i-k && l<r)///l始终要保证在[i-k,i]区间里,很多代码都是用while,其实每次l只加一个就够了
                l++;
            if(i>=k)
                printf("%d ",a[ dq[l] ] );
        }
        printf("
    ");
        l=r=0;
        dq[r++]=1;
        for(int i=2;i<=n;i++)
        {
            while(r>l && a[ dq[r-1] ]<a[i])
                r--;
            dq[r++]=i;
            if(dq[l]<=i-k && l<r)
                l++;
            if(i>=k)
                printf("%d ",a[ dq[l] ] );
        }
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    如果你很忙,你一定在什么地方做错了!
    NOSQL介绍
    mysql 8.0.11 安装(windows)
    ORA-28547:(Navicat Premium连接oracle报错)
    线性筛法
    Luogu-P1020(导弹拦截)(DP,LIS ,二分优化)
    POJ
    HDU
    HDU-1024-Max Sum Plus Plus(DP)
    UVA-1625-Color Length(DP LCS变形)
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/12632640.html
Copyright © 2011-2022 走看看