题目

设计一个最大栈数据结构,既支持栈操作,又支持查找栈中最大元素。

实现 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] - 栈没有改变

思路

这里的难点在 popMax 方法的实现,可以使用两个栈解题。

不断将原始栈的元素 pop 到缓存栈,遇到目标值 max,记录下来,再讲缓存栈的元素 pop 出来 push 进原始栈。

代码

1.


var MaxStack = function () {
    this.stack = [];
    this.maxStacks = [];
};

/** 
 * @param {number} x
 * @return {void}
 */
MaxStack.prototype.push = function (x) {
    this.stack.push(x);
    if (!this.maxStacks.length) {
        this.maxStacks.push(x)
    } else {
        const top = this.maxStacks[this.maxStacks.length - 1]
        let max = Math.max(top, x)
        this.maxStacks.push(max)
    }
};

/**
 * @return {number}
 */
MaxStack.prototype.pop = function () {
    this.maxStacks.pop()

    return this.stack.pop()
};

/**
 * @return {number}
 */
MaxStack.prototype.top = function () {
    return this.stack[this.stack.length - 1]
};

/**
 * @return {number}
 */
MaxStack.prototype.peekMax = function () {
    return this.maxStacks[this.maxStacks.length - 1];
};

/**
 * @return {number}
 */
MaxStack.prototype.popMax = function () {
    const tempStack = [];

    let max = this.peekMax();
    while (this.top() !== max) {
        tempStack.push(this.pop())
    }
    let temp = this.pop();

    while (tempStack.length) {
        this.push(tempStack.pop())
    }

    return temp
};

/**
 * Your MaxStack object will be instantiated and called as such:
 * var obj = new MaxStack()
 * obj.push(x)
 * var param_2 = obj.pop()
 * var param_3 = obj.top()
 * var param_4 = obj.peekMax()
 * var param_5 = obj.popMax()
 */