学算法刷LeetCode【剑指offer专题】:30.包含min函数的栈

277 阅读1分钟

题目描述

image.png

30.包含min函数的栈

解体思路

  1. 这道题只对时间复杂度有要求,那可以在空间复杂度上放宽。因此,我们可以使用两个栈,
  2. 栈1正常实现的 push、pop()、top() 等 API
  3. 栈2则用于实现 min()。栈2维护一个最小值,这里有两种维护的方法:
    • 一种是在 push 新元素的时候,把栈2的栈顶元素和新元素比较,把当前最小的值压入栈,这样栈2和栈1的元素个数始终相等,空间复杂度平均为 O(n);这样 pop 的时候,两个栈同时出栈即可。(见解法1)
    • 一种是在 push 新元素的时候,判断一下,只有栈2栈顶元素比新元素大的时候,再压入栈2,这样的话,栈2的元素和栈1的元素个数可能就不一样了,所以出栈的时候,pop方法也要进行判断,如果栈1出栈的元素和栈2出栈的元素的一样才需要出栈,否则栈2不操作。这个的最坏空间复杂度为 O(n), 我个人觉得除非数据量特别大,这点优化可以不用做。(见解法2)
      • push 时判断,如果栈2为空或者新元素小于等于栈2顶部元素,则添加到栈2

      • pop 时判断,栈1将要pop的元素与栈2是否相等,相等则需要将该元素也出栈。

代码

JS

解法1

var MinStack = function(){
    this.stack1 = [];
    this.stack2 = [Infinity];
}

MinStack.prototype.push = function(x){
    this.stack1.push(x);
    this.stack2.push(Math.min(this.stack2[this.stack2.length - 1], x));
}

MinStack.prototype.pop = function(){
    this.stack1.pop();
    this.stack2.pop();
}

MinStack.prototype.min = function(){
    return this.stack2[this.stack2.length - 1];
}

MinStack.prototype.top = function(){
    return this.stack1[this.stack1.length - 1];
}

解法2

var MinStack = function(){
    this.stack1 = [];
    this.stack2 = [];
}

MinStack.prototype.push = function(x){
    this.stack1.push(x);
    if(!this.stack2.length || this.stack2[this.stack2.length - 1] >= x){
        this.stack2.push(x)
    }
}

MinStack.prototype.pop = function(){
    const ele = this.stack1[this.stack1.length - 1];

    if(this.stack2[this.stack2.length - 1] == ele){
        this.stack2.pop();
    }

    this.stack1.pop();
}

MinStack.prototype.min = function(){
    return this.stack2.length ? this.stack2[this.stack2.length - 1] : 0
}

MinStack.prototype.top = function(){
    return this.stack1[this.stack1.length - 1];
}

时间复杂度: O(1) 空间复杂度: O(n)