栈和队列
在算法题目中,我们经常可以用两个栈来实现,基本栈功能以外的功能。
题目1,leetCode 155 Min Stack最小栈
设计一个支持push,pop,top操作,并能在常数时间内检索到最小元素的栈。
push操作:将元素入栈。
pop操作:删除栈顶的元素
top操作:获取栈顶元素
getMin操作:检索栈中的最小元素
解释:
算法题的解法大致分为两种:
时间换空间;空间换时间。
题目中要求时间复杂度为O(1),故可以考虑开辟额外的空间。其实也可以用vector或者List。但是本题恰好可以使用stack数据结构,来实现获取最小元素的功能。
在设计时,可以使用两个栈,一个栈用于保存,当前栈中的元素,其功能和一个正常的栈没有太大的区别stackData;另一个栈用于保存每一步的最小值,标记为stackMin。
对于这一思路,其实还有两种不同的实现方案,两者都是用stackMin保存着stackData的每一步的最小值。
共同特点是:
操作的时间复杂度为O(1),空间复杂度为O(n)。
区别是:
1.方案一种stackMin压入时稍省空间,但是弹出操作费时间。
2.方案二stackMin压入时稍费空间,但是弹出操作省时间。
设计方案一:
压入数据规则:
假设当前数据为ele,先将其压入stackData。然后判断stackMin是否为空:
如果为空,则ele也压入stackMin;如果不为空,则比较ele和stackMin的栈顶元素哪一个更小:如果ele更小或者两者相等,则ele也压入stackMin;如果stackMin中元素更小,不向stackMin中压入任何元素。数据弹出规则:
先在stackData中弹出栈顶元素,记为topValve,然后比较stackMin的栈顶元素和topValue哪个更小。
当topValue等于stackMin的栈顶元素时,stackMin弹出栈顶元素;
当topValue大于stackMin的栈顶元素时,stackMin不弹出元素,返回value。
查询当前栈中的最小值操作:
stackMin的栈顶元素始终是当前stackData中的最小值。
p.s.
其实,在写HalideIR的递归调用程序时,应该也经常用到栈这种数据结构,用于保存,递归过程中的某些特定值的特殊属性或标记。