【题目】
实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。
【要求】
1.pop、push、getMin()操作的时间复杂度都是O(1)。
2.设计的栈类型可以使用现成的栈结构。
【解答】
在设计上我们使用两个栈,一个栈用来保存当前栈中的元素,其功能和一个正常的栈没有区别,这个栈记为stackData;另一个栈用于保存每一步的最小值,这个栈记为stackMin。
压人规则:
假设当前数据为newNum,先将其压入stackData。然后判断stackMin是否为空:
如果为空,则newNum也压入stackMin。
如果不为空,则比较newNum和stackMin的栈顶元素哪一个更小:
如果newNum更小或两者相等,newNum也压入stackMin;
如果stackMin中栈顶元素小,则stackMin不压入任何内容。
弹出规则:
先在stackData中弹出栈顶元素,记为value。然后比较当前stackMin的栈顶元素和value值哪一个更小。通过压入规则可知,stackMin中存在的元素是从栈底到栈顶逐渐变小的,stack栈顶的元素既是stackMin栈的最小值,也是当前stackData栈的最小值。所以不会出现value比stackMin栈顶元素更小的情况,value只可能大于或者等于stackMin的栈顶元素。
当value等于stackMin的栈顶元素时,stackMin弹出栈顶元素;当value大于stackMin的栈顶元素时,stackMin不弹出栈顶元素,返回value。
查询当前栈中的最小值操作
stackMin始终记录着stackData中的最小值,所以,stackMin的栈顶元素始终是当前stackData中的最小值。
MyStack1.java:
1 package cn.hl.p1; 2 3 import java.util.Stack; 4 import org.junit.Test; 5 6 /** 7 * 设计一个有getMin功能的栈 8 * 题目:设计一个特殊的栈。在实现栈的基础功能上,再实现返回栈中最小元素的操作 9 * 要求: 10 * (1)pop,push,getMin操作的时间复杂度为O(1) 11 * (2)设计的栈类型可以使用现成的栈结构 12 * 13 * @author 猩生柯北 14 */ 15 16 public class MyStack1 { 17 private Stack<Integer> stackData; 18 private Stack<Integer> stackMin; 19 20 public MyStack1(){ 21 this.stackData = new Stack<Integer>(); 22 this.stackMin = new Stack<Integer>(); 23 } 24 25 public void push(int newNum){ 26 if(this.stackMin.isEmpty()){ 27 this.stackMin.push(newNum); 28 }else if(newNum <= this.getmin()){ 29 this.stackMin.push(newNum); 30 } 31 this.stackData.push(newNum); 32 } 33 34 public int pop(){ 35 if(this.stackData.isEmpty()){ 36 throw new RuntimeException("you stack is empty"); 37 } 38 int value = this.stackData.pop(); 39 if(value == this.getmin()){ 40 this.stackMin.pop(); 41 } 42 return value; 43 } 44 45 public int getmin() { 46 if(this.stackMin.isEmpty()){ 47 throw new RuntimeException("you stack is empty"); 48 } 49 return this.stackMin.peek(); 50 } 51 }
Test.java: