716. 最大栈
设计一个最大栈数据结构,既支持栈操作,又支持查找栈中最大元素。
实现 MaxStack 类:
-
MaxStack()
初始化栈对象 -
void push(int x)
将元素 x 压入栈中。 -
int pop()
移除栈顶元素并返回这个元素。 -
int top()
返回栈顶元素,无需移除。 -
int peekMax()
检索并返回栈中最大元素,无需移除。 -
int popMax()
检索并返回栈中最大元素,并将其移除。如果有多个最大元素,只要移除 最靠近栈顶 的那个。
示例:
输入
["MaxStack", "push", "push", "push", "top", "popMax", "top", "peekMax", "pop", "top"]
[[], [5], [1], [5], [], [], [], [], [], []]
输出
[null, null, null, null, 5, 5, 1, 5, 1, 5]
解释
MaxStack stk = new MaxStack();
stk.push(5); // [5] - 5 既是栈顶元素,也是最大元素
stk.push(1); // [5, 1] - 栈顶元素是 1,最大元素是 5
stk.push(5); // [5, 1, 5] - 5 既是栈顶元素,也是最大元素
stk.top(); // 返回 5,[5, 1, 5] - 栈没有改变
stk.popMax(); // 返回 5,[5, 1] - 栈发生改变,栈顶元素不再是最大元素
stk.top(); // 返回 1,[5, 1] - 栈没有改变
stk.peekMax(); // 返回 5,[5, 1] - 栈没有改变
stk.pop(); // 返回 1,[5] - 此操作后,5 既是栈顶元素,也是最大元素
stk.top(); // 返回 5,[5] - 栈没有改变
解法:双栈
复杂度
MaxStack | push | pop | top | peekMax | popMax | |
---|---|---|---|---|---|---|
时间复杂度 | O ( 1 ) O(1) O(1) | O ( 1 ) O(1) O(1) | O ( 1 ) O(1) O(1) | O ( 1 ) O(1) O(1) | O ( 1 ) O(1) O(1) | O ( n ) O(n) O(n) |
空间复杂度 | O ( n ) O(n) O(n) | O ( n ) O(n) O(n) | O ( n ) O(n) O(n) | O ( n ) O(n) O(n) | O ( n ) O(n) O(n) | O ( n ) O(n) O(n) |
代码
class MaxStack {
private:
stack<int> s1, s2;
public:
MaxStack() {}
void push(int x) {
s1.push(x);
int a = s2.empty() ? x : max(x, s2.top());
s2.push(a);
}
int pop() {
int x = s1.top();
s1.pop(), s2.pop();
return x;
}
int top() {
return s1.top();
}
int peekMax() {
return s2.top();
}
int popMax() {
int x = s2.top();
stack<int> s;
while (this->top() != x) s.push(this->pop());
this->pop();
while (s.size()) {
this->push(s.top()), s.pop();
}
return x;
}
};