剑指Offer(Java版):包含min函数的栈

题目:定义栈的数据结构,请在该类型中实现一个可以获得栈的最小元素的min函数。在该栈中,调用min,push及pop的时间复杂度都是O(1).java

看到这个问题,咱们的第一反应多是每次压入一个新元素进栈时,将栈里的全部元素排序,让最小的元素位于栈顶,这样就能在O(1)时间获得最小元素了。但这种思路不能保证最后压入的元素可以最早出栈,所以这个数据结构已经不是栈了。node

咱们接着想到在栈里添加一个成员变量存放最小的元素。每次压入一个新元素进栈的时候,若是该元素比当前最小的元素还要小,则更新最小元素。面试官听到这种思路以后就会问:若是当前最小的元素被弹出栈了,如何获得下一个最小的元素呢?面试

分析到这里咱们发现仅仅添加一个成员变量存放最小元素是不够的,也就是说当最小元素弹出栈的时候,咱们但愿可以获得次小元素。所以在压入这个最小元素以前,咱们要把次小元素保存起来。所以,在压入这个最小元素以前,咱们要把次小元素保存起来。数据结构

是否是能够把每次的最小元素都保存起来,放在另一个辅助栈里呢?咱们不妨举几个例子来分析一下把元素压入或者弹出栈的过程。函数

 

题关键在于用辅助栈储存什么值。要保证辅助栈的top是最小值,pop以后的顶部仍然是最小值。也就是说辅助栈从上到下存储的应该是最小值->次小值->次次小值……排序

这里容易进入一个误区就是:难道辅助栈就是对数据栈的排序?若是真是这样,push的时候由于要排序不能知足O(1);数据栈pop的时候,辅助栈要先查找数据栈pop出去的值而后再pop,也不知足O(1)。class

当两个栈为空时,push进去的第一个值即为最小值;import

push第二个元素时,若push的值<辅助栈顶元素(此处即第一个值),则将此值压进辅助栈;若push的值大于等于辅助栈顶元素,则将辅助栈顶元素再次push进去。变量

pop的时候,数据栈辅助栈均弹出顶元素。im

实现代码以下:

 

package cglib;

import java.util.Stack;

 

public class DeleteNode {
    Stack<Integer> stack1 = new Stack<Integer>(); // 数据栈
    Stack<Integer> stack2 = new Stack<Integer>(); // 辅助栈 用于返回min值
    
    
        public void push(int node) {
             stack1.push(node);
        if (stack2.empty()) {
                stack2.push(node);
            } else {
               if (node < stack2.peek().intValue())//若是进入的数小于辅助栈的栈顶元素
                   stack2.push(node);//则放进去进入的数
                 else stack2.push(stack2.peek());//不然放进辅助栈的栈顶元素
            }
    
        }
    
        @SuppressWarnings("null")
        public int pop() {
            
            if(stack1.empty()||stack2.empty()){
                
                return (Integer) null;
                }
                stack2.pop();
                return stack1.pop();
                }
       
    
        public int top() {
            if (!stack1.empty())
               return stack1.peek().intValue();
            else return 0;
         }
    
        public int min() {
            if (!stack2.empty())
                return stack2.peek().intValue();
            else return 0;
        }
    
        
    
            public static void main(String[] args) {
    
                DeleteNode ms = new DeleteNode();
    
                ms.push(4);
    
                ms.push(3);

                ms.push(1);
    
                ms.push(5);
    
                ms.push(2);//4,3,1,5,2
    
                
                //System.out.println("pop:" +ms.pop() );
                System.out.println("min:" + ms.min() + "  pop:" +ms.pop() );       
    
                System.out.println("min:" + ms.min() + "  pop:" +ms.pop() );       
    
               System.out.println("min:" + ms.min() + "  pop:" +ms.pop() );
               System.out.println("min:" + ms.min() + "  pop:" +ms.pop() );
    
        
    
            }
}

 

输出:

min:1  pop:2 min:1  pop:5 min:1  pop:1 min:3  pop:3

相关文章
相关标签/搜索