滑动窗口

【题目描述】

给定一个长度为N的数组,一个长为K的滑动窗体从最左端移至最右端,移动时只能看到窗体内的K个数,每次窗体向右移动一位,如下表:

Window positionMin valueMax value
[ 1 3 -1 ] -3 5 3 6 7-13
1 [ 3 -1 -3 ] 5 3 6 7-33
1 3 [ -1 -3 5 ] 3 6 7-35
1 3 -1 [ -3 5 3 ] 6 7-35
1 3 -1 -3 [ 5 3 6 ] 736
1 3 -1 -3 5 [ 3 6 7 ]37

现要求找出窗体在各位置时的Max value与Min value。

【输入描述】

第一行输入两个整数N、K;

第二行输入长度为N的数组。

【输出描述】

第一行输出每个位置的Min value;

第二行输出每个位置的Max value。

【样例输入】

8 3

1 3 -1 -3 5 3 6 7

【样例输出】

-1 -3 -3 -3 3 3

3  3  5  5  6 7

【数据范围及提示】

对于20%的数据,n <= 500;

对于50%的数据,n <= 100000;

对于100%的数据,n <= 1000000。

源代码:

#include<cstdio>
int n,k,i[1000001],Q[1000001],P[1000001];
void Min()
{
    int Head=1,Tail=0;
    for (int a=0;a<k-1;a++) //初始化。
    {
        while (Head<=Tail&&Q[Tail]>=i[a])
          Tail--;
        Q[++Tail]=i[a];
        P[Tail]=a;
    }
    for (int a=k-1;a<n;a++) //移动状态。
    {
        while (Head<=Tail&&Q[Tail]>=i[a]) //增尾。
          Tail--;
        Q[++Tail]=i[a];
        P[Tail]=a;
        while (P[Head]<a-k+1) //去头。
          Head++;
        printf(a==n-1?"%d\n":"%d ",Q[Head]); //注意换行。
    }
}
void Max() //同理于上。
{
    int Head=1,Tail=0;
    for (int a=0;a<k-1;a++)
    {
        while (Head<=Tail&&Q[Tail]<=i[a])
          Tail--;
        Q[++Tail]=i[a];
        P[Tail]=a;
    }
    for (int a=k-1;a<n;a++)
    {
        while (Head<=Tail&&Q[Tail]<=i[a])
          Tail--;
        Q[++Tail]=i[a];
        P[Tail]=a;
        while (P[Head]<a-k+1)
          Head++;
        printf(a==n-1?"%d\n":"%d ",Q[Head]);
    }
}
int main() //裸单调队列。
{
    scanf("%d%d",&n,&k);
    for (int a=0;a<n;a++)
      scanf("%d",&i[a]);
    Min();
    Max();
    return 0;
}

转载于:https://www.cnblogs.com/Ackermann/p/5861161.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值