Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
- push(x) -- Push element x onto stack.
- pop() -- Removes the element on top of the stack.
- top() -- Get the top element.
- getMin() -- Retrieve the minimum element in the stack.
建立一个栈功能可以有很多办法,比如利用动态数组,利用链表,这里选用STL中的VECTOR
考虑如下:
(1)getMin 功能,如果每次在当前栈里面遍历需找,太麻烦了切时间消耗过大;因此考虑重新建立一个栈,里面保存最小的值,当当前Pop掉的值不是最小值,则不变动最小栈,如果Pop掉的值是最小的,则同时Pop掉当前最小值。
一开始对于最小值栈的理解不够透彻,有两点没有想通:
1.如果有多个相同的最小值怎么处理,Pop掉最小值后,最小栈没有当前最小值了,但是原栈还有。
2.最小栈的入栈规则怎么确定,最开始我以为是来一个值,判断当前大小,在最小栈里面找到应该有的位置,后面才发现这个思路和每次遍历得到最小值没有什么区别。
后来确定的入栈规则是:
1.如果当前值小于最小等于最小栈的头值,则入栈。这里取可以等于,就排除了上一点1,如果有多个,就在最小栈保存多个。
还有一点没有想通的是,如果当前值A大于最小栈的头值怎么办?就不管了?那万一将当前最小值弹出以后,刚才那个值A变成最小值了呢???这一点想了很久才想通,假如原栈是S1,最小栈是S2,如果当前最小值是min,当前入栈值为data:
1.如果data<=min,则data应该设为最小值,因此两个栈都该压入。
2.如果data>min,则data不应设为最小值,因此只压入S1中,而在S1中,data永远先于min弹出!!这一点非常重要,保证了不会出现上面的情况,即弹出min后,data是最小值,因为data永远比min先弹出。
class MinStack {
public:
public:
void push(int x) {
mystack.push_back(x);
if (minstack.size() == 0)
{
minstack.push_back(x);
return;
}
if (minstack[minstack.size() - 1] >= x)
minstack.push_back(x);
}
void pop() {
if (minstack[minstack.size() - 1] == mystack[mystack.size() - 1])
minstack.erase(minstack.end()-1);
mystack.erase(mystack.end() - 1);
}
int top() {
if (mystack.size() >= 1)
return mystack[mystack.size()-1];
else
return NULL;
}
int getMin() {
if (mystack.size() == 0)
return NULL;
else
return minstack[minstack.size() - 1];
}
vector<int> mystack;
vector<int> minstack;
};