单调队列

单调队列是指:队列中元素之间的关系具有单调性,而且,队首和队尾都可以进行出队操作,只有队尾可以进行入队操作。


以单调不减队列为例:队列内的元素(e1,e2,e3...en)存在(e1<=e2<=e3<=...<=en)的关系,所以队首元素e1一定是最小的元素。与优先队列不同的是,当有一个新的元素e入队时,先要将队尾的所有大于e的元素弹出,以保证单调性,再让元素e入队尾。


例如这样一组数(1,3,2,1,5,6),进入单调不减队列的过程如下:

1入队,得到队列(1);

3入队,得到队列(1,3);

2入队,这时,队尾的的元素3>2,将3从队尾弹出,新的队尾元素1<2,不用弹出,将2入队,得到队列(1,2);

1入队,2>1,将2从队尾弹出,得到队列(1,1);

5入队,得到队列(1,1,5);

6入队,得到队列(1,1,5,6);


代码实现:

#include <iostream>

using namespace std;

class MonotonicQueue
{

#define MAXN 1000000

public:
	MonotonicQueue(void)
	{
		q = new int[MAXN+5];
		f = r = 0;
	}
	void push(const int val)
	{
		while (r > f && q[r-1] > val)	//弹出大于新元素的队尾元素
		{
			r--;
		}
		q[r++] = val;
	}
	int front(void)
	{
		if (f < r)
		{
			return q[f];
		}
		return 0;
	}
	void pop_front(void)
	{
		if (f < r)
		{
			f++;
		}
	}
	bool isEmpty(void)
	{
		return f == r;
	}
	void clear(void)
	{
		f = r = 0;
	}
	~MonotonicQueue(void)
	{
		delete q;
	}
private:
	int *q;
	int f;
	int r;
};

int main(void)
{
	MonotonicQueue mq;
	int n;
	while (cin >> n)
	{
		int i;
		for (i = 0; i < n; i++)
		{
			int a;
			cin >> a;
			mq.push(a);
		}

		while (!mq.isEmpty())
		{
			cout << mq.front() << endl;
			mq.pop_front();
		}
		mq.clear();
	}
	return 0;
}
访问队首和删除队首元素的时间复杂度为O(1),在队尾加入元素的最坏情况下的时间复杂度为O(n),n为队列当前长度。所以,可以采用二分查找,来确定新加入元素应该插入的位置。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

庞老板

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值