您的位置:首页 > 其它

栈与队列-单调栈,单调队列

2017-12-13 15:34 274 查看

什么时候使用?

单调栈

在均摊O(1) 即总时间复杂度为O(n)内实现找到某数右边第一个比它大(小)的数

单调队列

滑窗问题

在运行的过程中能够快速寻求前k个或后k个中最大或最小的值

我们直接来看实现吧

POJ3058发型糟糕的一天

#include <iostream>
#include <stdio.h>
#include <stack>
using namespace std;
stack<long> s;
int T;
long cnt;
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
scanf("%d",&T);

for(int i = 1; i <= T; i++)
{
long h;
scanf("%ld",&h);
while(!s.empty()&&(s.top() <= h))
{
s.pop();
}
cnt += s.size();
s.push(h);
}
// //一种会超时的解法
// for(int i = 1; i <= T; i++)
// {
//     for(int j = i+1; j <= T; j++)
//     {
//         if(a[j] < a[i])cnt++;
//         else break;
//     }
// }
// 考虑使用左右两个指针
// for(int l = 1, r = 2; l <= T && r <= T;l++)//其实几乎就是模拟队列的实现了
// {
//     while(r <= T && l > r)r++;
//     if(a[r] < a[l]) cnt++;
// }

printf("%ld\n",cnt);
#ifndef ONLINE_JUDGE
fclose(stdin); fclose(stdout);
#endif
return 0;
}


POJ3866滑动窗口

//看到这道题就回忆起单调栈&单调对列
//复习: 单调栈是用来寻找x后边第一个大于x的数
//单调队列是用来解决滑窗问题的 单调队列中的每一个元素都存储一个pair 第一个位表示它在

#include <iostream>
#include <string.h>
using namespace std;
const int N = 1e6 + 8;
int l, r;
int n, k;
int a
;
pair<int,int> q
;
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
scanf("%d%d",&n,&k);
l = 1;
r = 0;
for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
for(int i = 1; i <= n;i++)
{
while(r >= l && i - q[l].first >= k) l++;
while(r >= l && a[i] < q[r].second ) r--;
q[++r].first = i, q[r].second = a[i];
if(i >= k)printf("%d ",q[l].second);
}
printf("\n");
memset(q,0,sizeof(q));
l = 1, r = 0;
for(int i = 1; i <= n;i++)
{
while(r >= l && i - q[l].first >= k) l++;
while(r >= l && a[i] > q[r].second ) r--;
q[++r].first = i, q[r].second = a[i];
if(i >= k)printf("%d ",q[l].second);
}
printf("\n");
#ifndef ONLINE_JUDGE
fclose(stdin); fclose(stdout);
#endif
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: