• 155.最小栈


    image-20200512213059866


    • 本题核心是 实现得到栈中最小值的方法

    原文:https://leetcode-cn.com/problems/min-stack/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-38/

    双辅助栈

    思路

    • 一个栈保存正常的入栈出栈的元素,另一个栈去存最小值,即该栈的栈顶 保存当前栈中所有元素的最小值。

    • 具体步骤

      • 将第一个元素入栈。

      • 新加入的元素如果大于栈顶元素,那么新加入的元素就不处理。

      • 新加入的元素如果小于等于栈顶元素,那么就将新元素入栈。

      • 出栈元素不等于栈顶元素,不操作。

      • 出栈元素等于栈顶元素,那么就将栈顶元素出栈。

    • 实例

      入栈 3 
    |   |    |   |
      |   |    |   |
      |_3_|    |_3_|
      stack  minStack
      
      入栈 5 , 5 大于 minStack 栈顶,不处理
      |   |    |   |
      | 5 |    |   |
      |_3_|    |_3_|
      stack  minStack
      
      入栈 2 ,此时右边的 minStack 栈顶就保存了当前最小值 2 
      | 2 |    |   |
      | 5 |    | 2 |
      |_3_|    |_3_|
      stack  minStack
      
      出栈 2,此时右边的 minStack 栈顶就保存了当前最小值 3
      |   |    |   |
      | 5 |    |   |
      |_3_|    |_3_|
      stack  minStack
      
      出栈 5,右边 minStack 不处理
      |   |    |   |
      |   |    |   |
      |_3_|    |_3_|
      stack  minStack
      
      出栈 3
      |   |    |   |
      |   |    |   |
      |_ _|    |_ _|
      stack  minStack
      
    

    代码

        /*
         * 6ms
         */
    	
        private Stack<Integer> stack;
        private Stack<Integer> minStack;
    
        public MinStack() {
            stack = new Stack<>();
            minStack = new Stack<>();
        }
    
        public void push(int x) {
            stack.push(x);
            if (!minStack.isEmpty()) {
                int top = minStack.peek();
                //小于的时候才入栈
                if (x <= top) {
                    minStack.push(x);
                }
            }else{
                minStack.push(x);
            }
        }
    
        public void pop() {
            int pop = stack.pop();
    
            int top = minStack.peek();
            //等于的时候再出栈
            if (pop == top) {
                minStack.pop();
            }
    
        }
    
        public int top() {
            return stack.peek();
        }
    
        public int getMin() {
            return minStack.peek();
        }
    }
    

    单辅助栈 单变量存储min

    • 相对于双辅助栈 ,使用变量min存储最小值 (分析思路很妙)
    • 实例
    入栈 3
    |   |   min = 3
    |   |     
    |_3_|    
    stack   
    
    入栈 5 
    |   |   min = 3
    | 5 |     
    |_3_|    
    stack  
    
    入栈 2 
    | 2 |   min = 2?
    | 5 |     
    |_3_|    
    stack  
    
    

    如果只用一个变量就会遇到一个问题,如果把 min 更新为 2,那么之前的最小值 3 就丢失了。

    怎么把 3 保存起来呢?把它在 2 之前压入栈中即可。

    入栈 2 ,同时将之前的 min 值 3 入栈,再把 2 入栈,同时更新 min = 2
    | 2 |   min = 2
    | 3 |  
    | 5 |     
    |_3_|    
    stack  
    
    入栈 6 
    | 6 |  min = 2
    | 2 |   
    | 3 |  
    | 5 |     
    |_3_|    
    stack  
    
    出栈 6     
    | 2 |   min = 2
    | 3 |  
    | 5 |     
    |_3_|    
    stack  
    
    出栈 2     
    | 2 |   min = 2
    | 3 |  
    | 5 |     
    |_3_|    
    stack  
    

    上边的最后一个状态,当出栈元素是最小元素我们该如何处理呢?

    我们只需要把 2 出栈,然后再出栈一次,把 3 赋值给 min 即可。

    出栈 2     
    |   |  min = 3   
    | 5 |   
    |_3_|    
    stack  
    

    代码

    /*
     * 6ms
     */
    class MinStack {
        int min = Integer.MAX_VALUE;
        Stack<Integer> stack = new Stack<Integer>();
        public void push(int x) {
            //当前值更小
            if(x <= min){   
                //将之前的最小值保存
                stack.push(min);
                //更新最小值
                min=x;
            }
            stack.push(x);
        }
    
        public void pop() {
            //如果弹出的值是最小值,那么将下一个元素更新为最小值
            if(stack.pop() == min) {
                min=stack.pop();
            }
        }
    
        public int top() {
            return stack.peek();
        }
    
        public int getMin() {
            return min;
        }
    }
    
    

    链表实现(最直观)

    思路

    • 每添加一个节点,更新min值 且每次在链表头部加入节点

    代码

    /*
     * 5ms
     */
    class MinStack {
        class Node{
            int value;
            int min;
            Node next;
    
            Node(int x, int min){
                this.value=x;
                this.min=min;
                next = null;
            }
        }
        Node head;
        //每次加入的节点放到头部
        public void push(int x) {
            if(null==head){
                head = new Node(x,x);
            }else{
                //当前值和之前头结点的最小值较小的做为当前的 min
                Node n = new Node(x, Math.min(x,head.min));
                n.next=head;
                head=n;
            }
        }
    
        public void pop() {
            if(head!=null)
                head =head.next;
        }
    
        public int top() {
            if(head!=null)
                return head.value;
            return -1;
        }
    
        public int getMin() {
            if(null!=head)
                return head.min;
            return -1;
        }
    }
    

    原文请参考:https://leetcode-cn.com/problems/min-stack/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-38/

  • 相关阅读:
    【无中生有】---4----数据库设计-3
    【无中生有】---2---数据库设计-1
    redis3.0的demo实验
    redis3.0的demo实验
    那些在学习iOS开发前就应该知道的事(part 1)
    模板文件中的插件嵌入点列表
    图像处理框架 Core Image 介绍
    sharepoint services
    DiscuzX2.5数据库字典 值得学习
    Sublime Text 使用技巧
  • 原文地址:https://www.cnblogs.com/yh-simon/p/12879137.html
Copyright © 2020-2023  润新知