栈和队列--------设计一个有getMain功能的栈

题目

  实现一个特殊的栈,在实现栈的基本功能上,再实现返回栈中最小元素的操作。

要求

  1.  pop、push、getMain操作的时间复杂度是O(1)。

  2.  设计的栈类型可以使用现成的栈结构。

难度

  

解答

  在设计上我们使用两个栈,一个栈用来保存当前栈中的元素,其功能和一个正常的栈没有区别,这个栈记为stackData;另一个栈用于保存每一步的最小值,这个栈记为stackMin。具体的实现方式有两种。

  第一种设计方案如下

  •  压入数据规则

    假设当前数据为newNum,先将其压入stackData。然后判断stackMin是否为空:

    •  如果为空,则newNum也压入stackMin。

    •  如果不为空,则比较newNum和stackMin的栈顶元素中哪一个更小:

       •  如果newNum更小或两者相等,则newNum也压入stackMin。

       •  如果stackMin中栈顶元素小,则stackMin不压入任何内容。

    举例:依次压入3、4、5、1、2、1的过程中,stackData和stackMin的变化如图所示。

   •  弹出数据规则

    先在stackData中弹出栈顶元素,记为value。然后比较当前stackMin的栈顶元素和value哪一个更小。

    通过上文提到的压入规则可知,stackMin中存在的元素是从栈底到栈顶逐渐变小的,stackMin栈顶的元素是stackMin栈的最小值,也是当前stackData栈的最小值。所以不会出现value比stackMin的栈顶元素更小的情况,value只可能大于或等于stackMin的栈顶元素。

    当value等于stackMin的栈顶元素时,stackMin弹出栈顶元素;当value大于stackMin的栈顶元素时,stackMin不弹出栈顶元素;返回value。

    很明显可以看出,压入与弹出规则是对应的。

  •  查询当前栈中的最小值操作

    由上文的压入数据规则和弹出规则可知,stackMin始终记录着stackData中的最小值,所以,stackMin的栈顶元素始终是当前stackData的最小值。

  方案一的代码实现如下

 1 public class MyStack {
 2            private Stack<Integer>  stackData;
 3            private Stack<Integer>  stackMin;
 4 
 5            public  MyStack() {
 6                         this.stackData =  new Stack<Integer>();
 7                         this.stackMin   =  new Stack<Integer>();
 8            }           
 9 
10            public  void  push(int newNum) {
11                         if ( this.stackMin.isEmpty() ) {
12                                    this.stackMin.push(newNum);
13                         }else if ( newNum <= this.getMin() ) {
14                                    this.stackMin.push(newNum);
15                         }
16                         this.stackData.push(newNum);       
17            }
18 
19            public  int  pop() {
20                         if ( this.stackData.isEmpty() ) {
21                                    throw new RuntimeException("Your stack is empty.");
22                         }
23                         int value  =  this.stackData.pop();
24                         if ( value == this.getmin() ) {
25                                    this.stackMin.pop();
26                         }
27                         return value;
28            }
29 
30            public  int  getmin()  {
31                         if ( this.stackMin.isEmpty() )  {
32                                    throw new RuntimeException("Your stack is empty.");
33                         }
34                         return  this.stackMin.peek();
35            }
36 }                                                                    

  第二种设计方案如下

     未完待续。。。

原文地址:https://www.cnblogs.com/ZiyuanZhu/p/5312900.html