和我一起迎接明天的太阳吧

klaus08

焦虑源于行动的匮乏

JZ20 包含min函数的栈

原题链接

JZ20 包含min函数的栈

描述

定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数,并且调用 min函数、push函数 及 pop函数 的时间复杂度都是 O(1)。

push(value):将value压入栈中;

pop():弹出栈顶元素;

top():获取栈顶元素;

min():获取栈中最小元素。


示例

 输入:["PSH-1","PSH2","MIN","TOP","POP","PSH1","TOP","MIN"]
 返回值:-1,2,1,-1

思考

要求时间复杂度都是O(1),所以一定要保存最小值。

一开始的想法是用中间保存,每次push时更新,但忘了pop也会改变min的值,并且pop之后需要历史最小值。于是换了思路想用char[]保存最小值,但是发现当一个数同时在栈中出现9次以上(两位数)时,就没办法保存了。

最后看了题解有了如下两种解法:


解答

这种方法使用变量存储最小值,保证了每次在新的最小值之前啊,存储了上一次最小值

import java.util.Stack;


public class Solution {
    Stack<Integer> stack = new Stack<>();
    int tmp = 0x7fffffff;//存储最小值

    public void push(int node) {
        //一开始栈中没有元素
        if(stack.empty()) {
            stack.push(node);
            tmp=node;
        }else{
            //待入栈元素比当前最小值还小/相等
            if(node<=tmp){
                stack.push(tmp);//保存历史最小值
                tmp = node;//更新最小值
            }
            stack.push(node);//新元素入栈
        }
    }
    
    public void pop() {
        if(stack.empty()){}
        //2. 栈顶元素等于最小值
        if(tmp == stack.peek()){
            if(stack.size()>1){
                stack.pop();
                tmp = stack.peek();//上一个最小值
            }else{
                tmp =0x7fffffff;
            }
        }
        stack.pop();
        //1. 栈顶元素不等于最小值
    }
    
    public int top() {
        return stack.peek();
    }
    
    public int min() {
        return tmp;
    }
}

这个使用了两个栈。刚开始栈都空的时候,正常push第一个元素;

以后每次minStack值push自己栈顶元素与待入栈元素中最小的一个,依次来存储历史最小值。

import java.util.Stack;

//双栈,用另一个栈保存min
public class Solution {
    private Stack<Integer> dataStack = new Stack<>();
    private Stack<Integer> minStack = new Stack<>();

    public void push(int node) {
        dataStack.push(node);
        minStack.push(minStack.isEmpty() ? node : Math.min(minStack.peek(), node));
    }

    public void pop() {
        dataStack.pop();
        minStack.pop();
    }

    public int top() {
        return dataStack.peek();
    }

    public int min() {
        return minStack.peek();
    }
}

上面的方法二中,创建了一个辅助栈,但是该栈的大小和原栈相同下面这种方法稍稍做了改进,辅助栈的空间变小。

import java.util.LinkedList;

class MinStack {

    LinkedList<Integer> stack, min;

    public MinStack() {
        stack = new LinkedList<>();
        min =new LinkedList<>();
    }

    public void push(int x) {
        stack.addLast(x);
        if (min.isEmpty()) min.addLast(x);
        else if (x <= min.peekLast()) min.addLast(x);
    }

    public void pop() {
        if (stack.pollLast() == min.peekLast())
            min.pollLast();
    }

    public int top() {
        return stack.peekLast();
    }

    public int min() {
        return min.peekLast();
    }
}
posted @ 2021-07-11 11:09  klaus08  阅读(41)  评论(0)    收藏  举报