栈和队列
栈:先进后出
队列:先进先出
#include<iostream>
using namespace std;
const int N = 100010;
// ********************栈
int stk[N],tt=0;
//插入
stk[ ++ tt] = x;
//弹出
tt--;
//判断栈是否为空
if(tt > 0) not empty
else empty
//栈顶
stk[tt];
// ********************队列
//在队尾插入元素,在队头弹出元素
int q[N],hh=0,tt=-1;
//插入
q[ ++ tt]=x;
//弹出
hh++;
//判断队列是否为空
if(hh <= tt) not empty
else empty
//取出队头元素
q[hh];
单调栈和单调队列
单调栈:给定一个整数数列,输出每个数左边第一个比它小的数,如果不存在则输出 −1。
#include<stdio.h>
using namespace std;
const int N = 100010;
int n;
int stk[N],tt=0;
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
int x;
scanf("%d",&x);
while(tt && stk[tt]>=x) tt--;
if(tt) printf("%d ",stk[tt]);
else printf("-1 ");
stk[++ tt] = x;
}
return 0;
}
单调队列:输出滑动窗口中的最值
例题:
#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++;//因为滑动窗口每次只移动一位,所以用if不用while
while(hh<=tt && a[q[tt]]>=a[i]) tt--;
q[++tt]=i;
if(i-k+1>=0) printf("%d ",a[q[hh]]);
}
puts("");
//**************************输出滑动窗口的最大值
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>=0) printf("%d ",a[q[hh]]);
}
return 0;
}
KMP
#include<iostream>
using namespace std;
const int N = 100010,M = 1000010;
int n,m;
char p[N],s[M];
int ne[N];
int main()
{
cin >> n >> p+1 >> m >> s+1;
//求next的过程
for(int i=2,j=0;i<=n;i++)
{
while(j && p[i] != p[j+1]) j = ne[j];
if(p[i] == p[j+1]) j++;
ne[i]=j;
}
//kmp匹配过程
for(int i=1,j=0;i<=m;i++)
{
while(j && s[i]!=p[j+1]) j = ne[j];
if(s[i] == p[j+1]) j++;
if(j == n)
{
printf("%d ",i-n);
j = ne[j];
}
}
return 0;
}