zoukankan      html  css  js  c++  java
  • Week5 作业 D

    写单调队列时,其实一共有三个操作:取队头,弹出过期元素,加入新元素; 要结合实际循环和题目来决定在循环体内部这三个操作的顺序,顺序,顺序!有时感觉不恰当的时候,往往是顺序没设置完美 --编辑于2020.06.27

    题目描述:

    有一个长度为 n 的数列和一个大小为 k 的窗口, 窗口可以在数列上来回移动. 求在窗口从左往右滑的时候,每次窗口内数的最大值和最小值分别是多少. 例如:
    数列是 [1 3 -1 -3 5 3 6 7], 其中 k 等于 3.

    思路:

    求最小值时,维护一个单调递增队列,基本操作:

    ①元素进队操作:如果当前元素大于队尾则进队,否则弹出队尾,直到队空或者队尾元素小于当前元素;

    ②先把前k个元素都进队;

    ③从第k+1个元素到第n个元素遍历:遍历第i个元素时,当前队首的元素一定是第i-k个滑动窗口中的最小值;然后把过期的元素从队首删除,把第i个元素进队;遍历完n个元素之后,最后队首的元素是最后一个滑动窗口的最小值。

    同理可以用单调递减队列求最大值。

    正确性:

    单调递增队列中的队首元素一定是最小元素

     代码:

    值得注意的是,用G++交超时,用C++交能过,原因不想追究,因为我一直在寻找问题,直到题面更新了尝试G++和C++...

    STL的deque,支持队首和队尾都删除。 

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <queue>
     4 #include <deque>
     5 using namespace std;
     6 const int MAXN=1e6+5;
     7 deque<int> Q;
     8 int a[MAXN],maxi[MAXN],mini[MAXN];  //maxi[j]=k,第j个滑动窗口的最大值是k 
     9 int n,k;
    10 int main()
    11 {
    12     cin>>n>>k;
    13     for(int i=1;i<=n;i++)
    14         scanf("%d",a+i); 
    15     for(int i=1;i<=k;i++)
    16     {
    17         while( !Q.empty() && a[i]< a[ Q.back() ] )
    18             Q.pop_back();
    19         Q.push_back(i);
    20     }
    21     for(int i=k+1;i<=n;i++)
    22     {
    23         mini[i-k]=a[ Q.front() ];  //第i-k个滑动窗口的最小值就是队头
    24         while( !Q.empty() && i-Q.front()>=k )
    25             Q.pop_front();
    26         while( !Q.empty() && a[i]< a[ Q.back() ] )
    27             Q.pop_back();
    28         Q.push_back(i);
    29     }
    30     mini[n+1-k]=a[ Q.front() ];
    31     Q.clear();
    32     
    33     for(int i=1;i<=k;i++)
    34     {
    35         while( !Q.empty() && a[i]>a[ Q.back() ] )
    36             Q.pop_back();
    37         Q.push_back(i);
    38     }
    39     for(int i=k+1;i<=n;i++)
    40     {
    41         maxi[i-k]=a[ Q.front() ];  //第i-k个滑动窗口的最大值就是队头,但是i-k可能小于0,加了一个偏移MAXN 
    42         while( !Q.empty() && i-Q.front()>=k )
    43             Q.pop_front();
    44         while( !Q.empty() && a[i]>a[Q.back()] )
    45             Q.pop_back();
    46         Q.push_back(i);
    47     }
    48     maxi[n+1-k]=a[ Q.front() ];
    49         
    50     int t2=n-k+1;
    51     printf("%d",mini[1]);
    52     for(int i=2;i<=t2;i++)
    53         printf(" %d" , mini[i] );
    54     printf("
    %d",maxi[1]);
    55     for(int i=2;i<=t2;i++)
    56         printf( " %d" , maxi[i] );
    57     return 0; 
    58 }
  • 相关阅读:
    ASP.NET Core -- 安装版
    基础知识系列☞各版本下IIS请求处理过程区别
    基础知识系列☞IList ←vs→ List
    005杰信-factory删除数据
    004杰信-关于formSubmit('factorycreate.action','_self')路径的疑惑
    23SpringMvc_各种参数绑定方式-就是<input那种
    003杰信-在jsp页面输入数据,然后在oracle数据库中插入factory数据,当字段允许为空时要特殊处理
    spring+springmvc+mybatis+maven整合
    22SpringMvc_jsp页面上的数据传递到控制器的说明
    002Jsp的内置对象
  • 原文地址:https://www.cnblogs.com/qingoba/p/12615922.html
Copyright © 2011-2022 走看看