最小栈

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

  • push(x) —— 将元素 x 推入栈中。
  • pop() —— 删除栈顶的元素。
  • top() —— 获取栈顶元素。
  • getMin() —— 检索栈中的最小元素。

第一种方法是利用辅助栈

用一个栈存储数据,再用一个栈存储最小值
算法关键:

  1. 在一开始将Integer.MAX_VALUE压入辅助栈栈底
  2. 每当push一个新元素的时候,与辅助栈栈顶元素比较 将比较小的一个元素压入栈中(当辅助栈栈顶元素为最小值的时候压入一样的即可)
  3. 当pop一个元素的时候,辅助栈也一起pop

tips:pop、top 和 getMin 操作总是在 非空栈 上调用。

代码实现

package QueueAndStack.Stack;

import java.util.*;

/**
 * 最小栈
 * 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
 *
 * push(x) —— 将元素 x 推入栈中。
 * pop() —— 删除栈顶的元素。
 * top() —— 获取栈顶元素。
 * getMin() —— 检索栈中的最小元素。
 *
 */
public class MinStack {
  

//利用辅助栈实现最小栈
    /** initialize your data structure here. */
    Deque<Integer> stack;
    Deque<Integer> minStack;
    public MinStack() {
        stack=new LinkedList<>();
        minStack=new LinkedList<>();
        minStack.push(Integer.MAX_VALUE);
    }

    public void push(int x) {
        stack.push(x);
        //对比现在栈顶元素和当前元素大小  把小的入栈
        minStack.push(Math.min(minStack.peek(),x));
    }

    public void pop() {
        if (!stack.isEmpty()) {
            stack.pop();
            minStack.pop();
        }
    }

    public int top() {
        //空的时候不调用
        return stack.peek();
    }

    //空的时候不调用
    public int getMin() {
         return minStack.peek();
    }



}

第二种方法是利用差值

时间复杂度O(1),空间复杂度O(n)
定义一个数据栈存放差值diff ,定义一个minValue存放最小值
其中diff=node-minvalue node是新push的数据

算法关键:

  • push操作
    当栈为空的时候,数据栈压入0,minvalue压入node 因为第一个就是最小值 且差值为0
    当栈不为空的时候:
    diff<=0 此时nodeminvalue还小或者等于,所以此时把diff压入栈中 且minValue=nodediff>0 此时nodeminValue‘大 所以此时只需要把diff压入栈中
  • pop操作(需要考虑minvalue)
    取出栈顶获得diffdiff<=0 因为diff=node-minValue diff<=0说明node比较小或者等于最小值 那么node=diff+minvalue 所以之前的minvalue=现在的minvalue(也就是node)-diffminValue=minValue-diff 而当diff>0的时候
    说明node节点导入的时候不是最小值,不用修改minValue
  • pop操作
    diff<=0 直接返回minValuediff>0 返回node=diff+minValue

代码实现:

package QueueAndStack.Stack;

import java.util.*;

/**
 * 最小栈
 * 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
 *
 * push(x) —— 将元素 x 推入栈中。
 * pop() —— 删除栈顶的元素。
 * top() —— 获取栈顶元素。
 * getMin() —— 检索栈中的最小元素。
 *
 */
public class MinStack {
  


//利用差值 diff 2147483647 和-2147483648
    Deque<Integer> stack;
    int minValue;
    public MinStack() {
        stack=new LinkedList<>();
    }

    public void push(int x) {
        //栈为空的时候
        if (stack.isEmpty()){
            stack.push(0);//差值为0
            minValue=x;
        }else{
            int diff=x-minValue;
            if (diff>0){
                //说明x不是最小值 直接放进栈中
                stack.push(diff);
            }else{
                //说明x比最小值还小  更新最小值
                stack.push(diff);
                minValue=x;
            }
        }
    }

    public void pop() {
        int diff=stack.pop();//获取并删除栈顶元素
        if (diff<=0){
            //因为diff=x-minvalue  diff<=0说明x比较小或者等于最小值  那么x=diff+minvalue
            //所以之前的minvalue=现在的minvalue(也就是x)-diff
            minValue=minValue-diff;
        }
        //因为diff=x-minvalue  diff>0说明x比较大  那么x=diff+minvalue
        //所以minValue值不用变动
    }

    public int top() {
        int diff=stack.peek();
        return diff<=0?minValue:diff+minValue;
    }

    public int getMin() {
        return minValue;
    }

}