题目:
实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小的元素。
要求:
1.pop、push、getMin操作的实现复杂度都是O(1)。
2.设计的栈类型可以使用现成的栈结构。
解法:
设计两个普通栈来构造这个特殊栈,其中一个普通栈dataStack维持正常的出栈入栈操作,另一个栈minStack存储每一步出栈入栈的特殊栈内的最小值。
解法1
出栈的操作稍复杂一些。
import java.util.Stack;
public class getMinStack1 {
private Stack<Integer> dataStack;
private Stack<Integer> minStack;
public getMinStack1() {
this.dataStack = new Stack<Integer>();
this.minStack = new Stack<Integer>();
}
//压栈分析:
//dataStack维持正常压栈操作
//minStack为空或者当前需入栈元素小于等于栈顶元素时入栈,小于等于是为了和出栈操作一一对应。
public void push(Integer newNum) {
if(this.minStack.isEmpty() || newNum <= this.minStack.peek()){
this.minStack.push(newNum);
}
this.dataStack.push(newNum);
}
//出栈分析:首先判断栈内是否有元素,没有抛出异常。
//dataStack栈正常出栈,minStack当dateStack出栈元素对应时出栈,这里也解释了为什么入栈操作也要入栈等于元素
public Integer pop() {
if(this.dataStack.isEmpty()){
throw new RuntimeException("Your stack is empty! Please check!");
}
Integer value = this.dataStack.pop();
if(value == this.getMin()){
this.minStack.pop();
}
return value;
}
//直接获取minStack的栈顶元素即是栈中最小值
public Integer getMin() {
if(this.minStack.isEmpty()){
throw new RuntimeException("Your stack is empty!");
}
return this.minStack.peek();
}
}
解法2
入栈的操作稍复杂一些。
import java.util.Stack;
public class getMinStack2 {
private Stack<Integer> dataStack;
private Stack<Integer> minStack;
public getMinStack2() {
this.dataStack = new Stack<Integer>();
this.minStack = new Stack<Integer>();
}
//压栈操作:
//压栈栈空时,直接入栈。
//然后比较入栈元素和minStack的栈顶元素(就是当前栈中最小值),minStack入栈最小者。
//dataStack正常压栈。
public void push(Integer newNum){
if(this.minStack.isEmpty()){
this.minStack.push(newNum);
}else if(this.getMin() <= newNum){
this.minStack.push(this.getMin());
}else{
this.minStack.push(newNum);
}
this.dataStack.push(newNum);
}
//出栈操作:
//判断是否栈空,栈空抛出异常。
//因为入栈操作缘故,出栈直接保持两栈同步出栈即可。
public Integer pop(){
if(this.dataStack.isEmpty()){
throw new RuntimeException("Your stack is empty!");
}
this.minStack.pop();
return this.dataStack.pop();
}
//minStack的栈顶元素即是当前栈中的最小值。
public Integer getMin(){
if(this.minStack.isEmpty()){
throw new RuntimeException("Your stack is Empty!");
}
return this.minStack.peek();
}
}
测试
import StackQueue.getMinStack.getMinStack1;
import StackQueue.getMinStack.getMinStack2;
public class getMinStackTest {
public static void main(String[] args) {
getMinStack1 stack1 = new getMinStack1();
stack1.push(3);
System.out.println(stack1.getMin());
stack1.push(4);
System.out.println(stack1.getMin());
stack1.push(5);
System.out.println(stack1.getMin());
stack1.push(1);
System.out.println(stack1.getMin());
System.out.println(stack1.pop());
System.out.println(stack1.pop());
System.out.println(stack1.getMin());
stack1.push(2);
System.out.println(stack1.getMin());
stack1.push(1);
System.out.println(stack1.getMin());
System.out.println("------------------------------");
getMinStack2 stack2 = new getMinStack2();
stack2.push(3);
System.out.println(stack2.getMin());
stack2.push(4);
System.out.println(stack2.getMin());
stack2.push(5);
System.out.println(stack2.getMin());
stack2.push(1);
System.out.println(stack2.getMin());
System.out.println(stack2.pop());
System.out.println(stack2.pop());
System.out.println(stack2.getMin());
stack2.push(2);
System.out.println(stack2.getMin());
stack2.push(1);
System.out.println(stack2.getMin());
}
}
运行结果:
分别对两个方法进行测试,得到一致的结论。