设计包含min函数的栈。
定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。
要求函数min、push以及pop的时间复杂度都是O(1)。
解析:push和pop都可以做到时间复杂度为O(1),则函数min是关键,如果仅是用一个变量来记录当前最小值,一旦这个最小值被pop出去,便找不到剩下所有变量中的最小值了。
我们需要一个辅助栈来记录,原数据栈中按照后进先出的原则,而辅助栈则将数据按照顺序进栈,最小值在栈顶。
举例:
通过举例我们容易看到这个方法还是有一定不足的。1、辅助栈总是在添加新元素时会改变元素的顺序,会间接增加时间的消耗,最坏情况是全部出栈,把新push元素放入栈底,然后再全部入栈,为O(2N);2、如果数据的结构比较复杂,则会增加空间的消耗。
改进:
如果栈是以数组的方式存储的话,我们知道数组的随机访问时间复杂度为O(1),那么我们只需要记录最小元素在原栈中的位置,由于栈后进先出的特点,如果新push的元素比最小元素小,则需记录该元素位置,如果新push元素比最小元素大,则辅助栈push的元素是最小元素位置的大小。
举例:
这样一来,空间复杂度降低了,时间复杂度也降低了。
从 5.push 6 5,7,1,3,0 0,0,2,2,41可以看出辅助栈中多了很多不需要的空间,0和2都有重复。
如果入栈的元素都不相等,那么可以省略重复的部分,在步骤5辅助栈中应该是0 2 4,当出栈元素是最小元素时,辅助栈才出栈。
如果入栈有相等的元素,那么辅助栈需要有相等的元素或者其他标记来记录重复的个数。
继续改进:
如果不能用辅助栈呢?我们来定义一个数据结构
template <typename T> class MinStack
{
private:
T m_data;
class MinStack * m_minLink;
};