开拓计划1 - 栈与队列
开拓计划1 - 栈与队列
栈与队列的概念及作用
栈的概念
- Q:什么是栈?
- A:栈是一种后进先出 (BIFO) 的数据结构。
栈的作用
- Q:栈有什么作用?
- A:只要满足栈的定义的场景都可以使用栈。eg:括号匹配,火车进站 etc. 计算后缀表达式时也会使用。
队列的概念
-
Q:什么是队列?
-
A:队列是一种先进先出 (FIFO) 的数据结构。
队列的作用
- Q:队列有什么作用?
- A:只要满足队列的定义的场景都可以使用栈。eg:排队 ,舞会 etc. 。
NKOJ 1914 火车调度
思路:判断出栈顺序是否合法
实现方法
- 如果栈顶小于我当前的元素,我可以通过添加元素的操作来使它有这个元素,并弹出。
- 如果栈顶等于我当前的元素,直接弹。
- 如果栈顶大于我当前的元素,不可能通过调整栈来完成,直接
No
。
注意事项
- 在开始时要提前加入0,不然第一次访问top时会
RE
。 - 遇到不可能后要直接结束,否则会死循环。
单调队列
单调的概念及作用
- Q:什么是单调性?
- A:单调是指一个序列如果它从头到尾一个比一个大 / 小,这个序列就是单调递增 / 单调递减的。
- Q:单调队列有什么作用?
- A:可以根据题目需要,在 \(O_n\) 内知道一个元素左 / 右边第一个比它大 / 小的元素。
单调队列的使用细节
- Q:为什么用双端队列?
- A:因为双端队列可以在头或尾任意添加或删除元素,不受队列 / 栈的性质的限制。
- Q:为什么存放下标而非值?
- A:因为在滑动窗口问题中,下标的大小能够判断窗口的范围,在很多题目中,队列的下标也是有很多作用的。
NKOJ 3767 仰望
思路:单调队列模板题
实现方法:
- 如果当前遍历到的元素满足单调性将其加入
- 不然把不满足的全删掉,让它们仰望当前元素
多种实现方法:
法一:判断队列是不是为空
法二:开始时提前加入0,不用判空,但是要判栈顶为不为0
注意事项:
-
当用法一时,注意先写判空再写比较,如果先比较而栈此时是空的,就会
RE
,示例:正确:stk.empty()==1||arr[stk.top()]>arr[i] 错误:arr[stk.top()]>arr[i]||stk.empty()==1
NKOJ 5423 数糖纸
思路:用了单调队列的思想,不是模板。
实现方法:
- 遍历输入的颜色。
- 对于每种颜色:
- 如果这个颜色之前没出现过,就打标记并加入收集队列。
- 否则,就将上一次出现这个颜色,与这次之间的颜色出队。(因为区间只能连续,颜色又出现了重复,已经收集的区间必须放弃,没有必要)
注意事项:
- 在用
map
做统计 / 标记工作时,可以使用unordered_map
来减少时间。
单调队列与双指针
-
单调队列的滑动窗口和双指针的滑动窗口有共通之处,但实现方法天差地别。
-
单调队列:需要求的是窗口内的最大最小值,此时使用单调队列,因为极值不满足加减性。侧重点:求极值。
-
双指针:需要求的是和为 \(x\) 的数的个数,此时在大了或小了时改变窗口大小,和用前缀和求。侧重点:窗口大小的变化。