leetCode155. Min Stack

题目描述:
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.

  • push(x) – Push element x onto stack.
  • pop() – Removes the element on top of the stack.
  • top() – Get the top element.
  • getMin() – Retrieve the minimum element in the stack.

例子:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); –> Returns -3.
minStack.pop();
minStack.top(); –> Returns 0.
minStack.getMin(); –> Returns -2.

思路:

首先分析一下这个题,其中这个题目的入栈和出栈操作与我们以前接触的栈操作是无任何区别的,唯一的区别就是我们可以随时获取到栈中的最小值。那么就需要我们在入栈和出栈的时候随时记录到目前为止栈中的最小值。此处,利用了栈sMin作为辅助,用以保存当前栈中的最小值
举个例子吧,如果push 1,那么栈s中为 1,栈sMin中为1
push-2,栈s中为1,-2,栈sMin中为1,-2
push0,栈s中,1,-2,0,栈sMin中为1,-2,-2
可以看出sMin是s中对应的截止到当层栈中的最小值
min维护了目前的最小值
push操作:
对于栈s,直接push,而对于栈sMin,对比min和要入栈的值x,如果栈sMin为空,则直接将x入栈sMin并且赋值给min;或者如果x

class MinStack {
    private Stack<Integer> s;
    private Stack<Integer> sMin;
    private int min = Integer.MAX_VALUE;
    /** initialize your data structure here. */
    public MinStack() {
        s = new Stack<Integer>();
        sMin = new Stack<Integer>();
    }
    public void push(int x) {
        s.push(x);
        if(sMin.empty() || x < min){
            sMin.push(x);
            min = x;
        }
        else{
            sMin.push(min);
        }
    }

    public void pop() {
        s.pop();
        sMin.pop();
        if(!sMin.empty())
            min = sMin.peek();
        else 
            min = Integer.MAX_VALUE;
    }

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

    public int getMin() {
        return sMin.peek();
    }
}

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.push(x);
 * obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.getMin();
 */

另一种的实现思路:
不利用栈,而是创建链表,与上述的主要想法还是一致的,就是不仅记录当前入栈的值,还记录到目前为止的栈中的最小值

class MinStack {
    private Node head;
    public void push(int x) {
        if(head == null)
            head = new Node(x,x,null);
    else     //头插法建立链表
        head = new Node(x,Math.min(x,head.min),head);
    }

    public void pop() {
    //弹栈相当于删除一个节点
        head = head.next;
    }

    public int top() {
        return head.val;
    }

    public int getMin() {
        return head.min;
    }
    //每个节点保存当前要入栈的值及目前的最小值
    private Class Node{
    private int val;
    private int min;
    private Node next;
    private Node(int val,int min){
        this(val,min,null);
    }
    private Node(int val,int min,Node next){
        this.val = val;
        this.min = min;
        this.next = next;
    }
    }

}

再一种思路:
仅仅创建一个栈就可以解决
先po代码,再解释

class MinStack {
    Stack<Integer> stack=new Stack<>();
    int min=Integer.MAX_VALUE;
    public void push(int x) {
        // only push the old minimum value when the current 
            // minimum value changes after pushing the new value x
        if(x<=min) {
            stack.push(min); 
            min=x;
        }
        stack.push(x);
    }
    public void pop() {
        if(stack.peek()==min){ 
            stack.pop(); 
            min = stack.pop();
        }
        else 
            stack.pop();
    }
    public int top() {
        return stack.peek();
    }
    public int getMin() {
        return min;
    }
}
//可以说这种思路很巧妙
/*
每次入栈时执行的操作是这样的,如果待入栈的值x是当前栈中的最小值,那么将先前的最小值入栈保存,然后更新min值,最后再将x入栈
出栈时,如果栈顶的元素是与min值相等,证明最小的元素要出栈了,则此时min值发生改变,更新为栈顶元素,因为我们先前入栈的时候,每入栈时,首先将先前的最小值保存;如果不想等,则证明该元素对min值无影响,直接出栈即可
*/

画图示意:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值