设计包含min函数的栈

来源:互联网 发布:湛庐文化 知乎 编辑:程序博客网 时间:2024/04/27 19:08

设计包含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;

};


当新push元素大于最小元素时,放在链表尾端,如果新push元素小于最小元素时,需要将最小元素放在链表首位。pop时等同于删除链表中的一个节点。
这个方法虽然省略了辅助栈,但复杂了数据的结构。
0 0
原创粉丝点击