#include <iostream>
#include <stdio.h>
#include <stack>
#include <string>
using namespace std;
/*
问题:请设计一个栈,除pop与push方法,还支持min方法,可返回栈元素中的最小值。
push,pop,min三个方法的时间复杂度为O(1)
分析:能否再普通栈的基础上维持一个最小元素的值,获取最小值时就返回它。
关键是如何找到最小值下面的次最小值?
寻找此最小值的过程可能需要把所有元素拿出来比较。
除非设置一个排好序的栈。
书上解法:
牛叉。直接用另一个栈来记录最小值。压入时,除了栈本身压入元素外,如果当前元素<=最小值,那么压入第二个栈中。【防止后面当前元素=最小值时弹出该元素后,后续就没有最小值】
弹出时,如果当前元素等于最小值时,第二个栈也弹出元素。
求最小值时,就返回当前栈的栈顶元素。
我之所以未能做出:就是把思维局限在只有一个栈上,求最小值需要遍历该栈。而正确的做法直接用另外一个栈保存最小值,里面记录了最小值,就不需要遍历操作。
输入:
4(输入栈的元素个数)
5 6 3 7
1(指令个数)
pop 2(pop次数2次)
输出:
5
关键:
1 采用栈中保存另一个栈来记录最小值。在每一次插入元素时,当前元素<=最小值时,就将最小值压入第二个栈中。
弹出时,当前元素=最小值时,第二个栈也弹出最小值
*/
class MinStack : public stack<int>
{
public:
MinStack(){}
void push(int value)
{
stack<int>::push(value);
//如果当前元素的值 <= 最小值,就压入最小元素,这里等于时要压入,否则后续当前元素=最小值 弹出元素后会导致下次遇到同样情况,无法弹出最小元素
if( value <= min() )
{
minStack.push(value);
}
}
void pop()
{
int value = stack<int>::top();
stack<int>::pop();
//如果当前值就是最小值,弹出最小栈中对应最小值
if(value == min())
{
minStack.pop();
}
}
int min()
{
if( minStack.empty() )
{
return INT_MAX;
}
else
{
return minStack.top();
}
}
private:
stack<int> minStack;
};
int main(int argc, char* argv[])
{
int n , commandNum;
while(cin >> n)
{
int* pArr = new int[n];
MinStack minStack;
for(int i = 0 ; i < n ; i++)
{
cin >> *(pArr + i) ;
minStack.push( *(pArr + i) );
}
//获取命令
cin >> commandNum;
string command;
int value;
for(int j = 0 ; j < commandNum ; j++)
{
cin >> command >> value;
if(command == "pop")
{
for(int k = 0 ; k < value ; k++)
{
minStack.pop();
}
}
else if(command == "push")
{
minStack.push(value);
}
}
//输出最小元素
cout << minStack.min() << endl;
delete[] pArr;
}
getchar();
return 0;
}