题目描述:
设计一个最大栈,支持 push、pop、top、peekMax 和 popMax 操作。
push(x) – 将元素 x 压入栈中。
pop() – 移除栈顶元素并返回这个值。
top() – 返回栈顶元素。
peekMax() – 返回栈中最大元素。
popMax() – 返回栈中最大的元素,并将其删除。如果有多个最大元素,只要删除最靠近栈顶的那个。
样例 1:
MaxStack stack = new MaxStack();
stack.push(5);
stack.push(1);
stack.push(5);
stack.top(); -> 5
stack.popMax(); -> 5
stack.top(); -> 1
stack.peekMax(); -> 5
stack.pop(); -> 1
stack.top(); -> 5
注释:
-1e7 <= x <= 1e7
操作次数不会超过 10000。
当栈为空的时候不会出现后四个操作。
方法1:
主要思路:
(1)使用两个栈实现,一个栈作为正常的存储数据元素的栈st,另一个只存储递增元素st_max,既只有当前要压入的元素大于等于之前的所有元素时,才进行压入到栈st_max中;
(2)但是后面处理pop和popMax时,要注意同时处理两个栈;
class MaxStack {
public:
stack<int> st;
stack<int> st_max;
/** initialize your data structure here. */
MaxStack() {
}
void push(int x) {
//将元素压入到栈中
st.push(x);
//根据情况,压入到最大栈st_max中
if(st_max.empty())
st_max.push(x);
else if(x>=st_max.top())
st_max.push(x);
}
int pop() {
//弹出栈中的元素
int tmp=st.top();
st.pop();
//根据情况,弹出最大栈st_max中的元素
if(tmp==st_max.top())
st_max.pop();
return tmp;
}
int top() {
return st.top();
}
int peekMax() {
return st_max.top();
}
int popMax() {
int tmp=st_max.top();
st_max.pop();//先获得当前的最大值
stack<int>st_tmp;
while(st.top()!=tmp){//将最大值前面的元素弹出,保存到临时的栈中
st_tmp.push(st.top());
st.pop();
}
st.pop();//弹出最大元素
while(!st_tmp.empty()){//将临时栈中的元素压回到栈中
int top_num=st_tmp.top();
st.push(top_num);
st_tmp.pop();
//因为之前的最大值已经弹出,则最大栈st_max也可能同步的更新
if(st_max.empty()){
st_max.push(top_num);
}
else if(top_num>=st_max.top()){
st_max.push(top_num);
}
}
return tmp;//返回最大值
}
};
/**
* Your MaxStack object will be instantiated and called as such:
* MaxStack* obj = new MaxStack();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->peekMax();
* int param_5 = obj->popMax();
*/