栈和队列

先进后出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// tt表示栈顶
int stk[N], tt = 0;

// 向栈顶插入一个数
stk[ ++ tt] = x;

// 从栈顶弹出一个数
tt -- ;

// 栈顶的值
stk[tt];

// 判断栈是否为空
if (tt > 0)
{
// 不空
}

队列

普通队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// hh 表示队头,tt表示队尾
int q[N], hh = 0, tt = -1;

// 向队尾插入一个数
q[ ++ tt] = x;

// 从队头弹出一个数
hh ++ ;

// 队头的值
q[hh];

// 判断队列是否为空
if (hh <= tt)
{
//不为空
}

循环队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// hh 表示队头,tt表示队尾的后一个位置
int q[N], hh = 0, tt = 0;

// 向队尾插入一个数
q[tt ++ ] = x;
if (tt == N) tt = 0;

// 从队头弹出一个数
hh ++ ;
if (hh == N) hh = 0;

// 队头的值
q[hh];

// 判断队列是否为空
if (hh != tt)
{

}

单调栈

返回一个数左边且比他小的数,没有返回-1
20220111181656

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

常见模型:找出每个数左边离它最近的比它大/小的数
int tt = 0;
for (int i = 0; i < n; i ++ )
{
//看是更大(从栈里面找,也就是栈顶 > x ==》输出,<=x 弹出栈)还是更小,
while (tt && check(stk[tt], i)) tt -- ;
//---
if(tt)

//可以不存结果,直接输出
//---
stk[ ++ tt] = i;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

常见模型:找出每个数右边边离它最近的比它大/小的数
int tt = 0;
for (int i = n-1; i >= 0; i -- )
{
//看是更大(从栈里面找,也就是栈顶 > x ==》输出,<=x 弹出栈)还是更小,
while (tt && check(stk[tt], i)) tt -- ;
//---
if(tt)

//存入结果
ans[i]=stk[tt]
//---
stk[ ++ tt] = i;
}

20220111184157

单调队列

1
2
3
4
5
6
7
8
9
常见模型:找出滑动窗口中的最大值/最小值
int hh = 0, tt = -1;
for (int i = 0; i < n; i ++ )
{
while (hh <= tt && check_out(q[hh])) hh ++ ; // 判断队头是否滑出窗口,可以写if
while (hh <= tt && check(q[tt], i)) tt -- ;
q[ ++ tt] = i;
}

20220111203319