【单调队列】

北大POJ上有一道单调队列的经典例题:模板题

本题大意是给出一个长度为 n的数组,编程输出每k个连续的数中的最大值和最小值。
最暴力的想法很简单,对于每一段的序列i ~ i+k-1,逐个比较来找出最大值(和最小值),时间复杂度约为O(n*k)
很显然,这其中进行了大量重复工作,除了开头k-1个和结尾k-1个数之外,每个数都进行了k次比较,而题中100%的数据为n<=1000000,当稍大的情况下,显然会 TLE。

这时所用到的就是单调队列了。
(1)概念:
顾名思义,单调队列的重点分为 “单调” 和 “队列
单调” 指的是元素的的 “规律”——递增(或递减)
队列” 指的是元素只能从队头和队尾进行操作

在这里插入图片描述
在这里插入图片描述

Acwing_154滑动窗口 这道题目跟上面一道题目类似

AC代码:

#include<iostream>

using namespace std;

const int N = 1000010;
int n,k;
int a[N], q[N];
int main()
{
	scanf("%d%d", &n,&k);
	for (int i = 0; i < n; i++) scanf("%d", &a[i]);
	int hh = 0, tt = -1;
	for (int i = 0; i < n; i++) {
		if (hh <= tt && i - k + 1 > q[hh]) hh++;
		while (hh <= tt && a[q[tt]] >= a[i]) tt--;
		q[++tt] = i;
		if (i >= k - 1) printf("%d ", a[q[hh]]);
	}
	printf("\n");

	hh = 0, tt = -1;
	for (int i = 0; i < n; i++) {
		if (hh <= tt && i - k + 1 > q[hh]) hh++;
		while (hh <= tt && a[q[tt]] <= a[i]) tt--;
		q[++tt] = i;
		if (i >= k - 1) printf("%d ", a[q[hh]]);
	}

	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值