简单单调队列原理

单调队列用最简单的理解就是在一个数组a中求所有的k个连续元素内(定义为一个视窗)的最大的元素:

维护一个类似队列的数组b从队尾依次添加原数组的元素j,此时队首的元素i位置在视窗外(i<j-k,删除它;再从队尾向前,所有小于a[j]的元素都删除,保证队列队尾到队首呈递增状;对于队首元素i,如果ij是整个视窗(j --  i = k ),那么队首i元素就是视窗内最大的;如果i在视窗内部(j - i ),从j-ki那部分元素i(或更前面)的元素删除了,而这部分元素肯定都在i(或更小)元素所对应的视窗内i(或更小)元素要比这部分元素大才能进行删除,所以从j-ki的元素i元素也比它们都大,所以这个队列维护的队首即为 jj-k最大的元素。(想当与维护了出一个递减的序列,比一般方法就减少了时间复杂度)

代码:

memset(b,0,sizeof(b));//存放相应序号的队列
        for(int i=0; i<n; i++)
scanf("%d",&a[i]);
        for(int j=0,
s=0,e=0; j<n; j++)

        {
            if(j-b[s]>=k)s++;//队首在视窗外
            while(e>=s&&a[j]>a[b[e]])e--;//去除比新加元素小的
            b[++e]=j;
            printf("%d\n",a[b[s]]);
        }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值