栈及经典问题(一)

一、栈的基础知识

栈是⼀种“先进后出”(FILO, First In Last Out)的数据结构。

二、经典面试题

1.栈的基本操作

LeetCode #面试题03.04 化栈为队

利⽤两个栈来实现,⼀个输⼊栈、⼀个输出栈。

输⼊栈⽤于读⼊数据。当需要输出元素时,若输出栈为空,则将输⼊栈的所有元素 推送到输出栈,然后取栈顶元素;若输出栈⾮空,则输出栈顶即可。

输出栈的作⽤是对已经被反转的序列进⾏⼆次反转。对此感到困惑的同学可以画图模拟⼀下。

LeetCode #844 比较含退格的字符串

按照题意实现即可。

LeetCode #946 验证栈序列

被出栈的元素只有两种可能:即将⼊栈的元素 和 当前栈顶的元素。

只需要关注出栈序列,分类讨论后模拟即可。

2.栈结构扩展应用

LeetCode #20 有效的括号

结论1:在任意⼀个位置上,左括号数量>=右括号数量

结论2:在最后⼀个位置上,左括号数量==右括号数量

根据上述两个结论,程序中只需要记录左括号和右括号的数量即可。

⼀对括号可以等价为⼀个完整的事件。左括号可以看作事件的开始、右括号可以看

作事件的结束。⽽括号序列可以看作事件与事件之间的完全包含关系。

栈可以处理具有完全包含关系的问题。

LeetCode #1021 删除最外层的括号

左括号和右括号差值为0时,代表这⼀串括号序列是独⽴的,可以被单独分解出来。

LeetCode #1249 移除⽆效的括号

可以被匹配的括号都是有效的,⽽其他的括号都需要被删除。

LeetCode #145 ⼆叉树的后序遍历

递归做法⽐较简单,在这⾥介绍⼀下基于迭代的做法。

技巧是使⽤两个栈,⼀个数据栈,⼀个状态栈。将“遍历左⼦树”,“遍历右⼦树”和“访问根节点”三个步骤分别⽤状态码表⽰,枚举状态转移过程,使⽤有限状态⾃动机(FSM, Finite State Machine)的模型来模拟递归过程。

LeetCode #331 验证⼆叉树的前序序列化

思路1:每次拆掉⼀个“数字、#、#”的节点(即叶⼦结点),最后树上的全部节点都会被拆光(即只剩⼀个“#”),能拆光的序列就是合法序列。

思路2:初始状态有⼀个坑。每多增加⼀个数字节点,会在占掉⼀个坑后,产⽣两个坑,每多增加⼀个#,会减少⼀个坑。合法的⼆叉树前序遍历最后会刚好⽤完所有的坑。

LeetCode #227 基本计算器II

思路1:找到式⼦中优先级最低的运算符,然后递归分治运算两侧的⼦式即可。

思路2:使⽤操作数栈和操作符栈辅助计算,当操作符栈遇到更低优先级的操作符时,需要将之前更⾼级别的操作符对应的结果计算出来。

对于有括号的情况,左括号相当于提⾼了内部全部运算符的优先级,当遇到右括号的时候需要将匹配的括号间的内容全部计算出来。

可以通过加⼀个特殊操作符的处理技巧,来额外处理结尾的数字。

智力发散题

LeetCode #636 函数的独占时间

本质就是⼀道模拟题,画⼀个线段图能显著地辅助理解。任务开始时进栈,上⼀个任务暂停执⾏;任务完成时出栈,恢复上⼀个任务的执⾏。

你可能感兴趣的:(数据结构,笔记,面试,数据结构,算法)