package com.example.demo.algorithm.D002;
import java.util.Stack;
/**
* @Description :
* 返回栈中的最小值
*
* @Author : Darren
* @Date : 2021 年 02 月 18 日 20:41:07
* @since : 1.0
*/
public class J005_GetStackMin {
public static void main(String[] args) {
MyStack1 myStack1 = new MyStack1();
myStack1.push(5);
System.out.println(myStack1.getMin());
myStack1.push(2);
System.out.println(myStack1.getMin());
myStack1.push(6);
System.out.println(myStack1.getMin());
System.out.println(myStack1.pop());
System.out.println(myStack1.getMin());
System.out.println("~~~~~~~~~~~~~~~~~~~~");
MyStack2 myStack2 = new MyStack2();
myStack2.push(5);
System.out.println(myStack2.getMin());
myStack2.push(2);
System.out.println(myStack2.getMin());
myStack2.push(6);
System.out.println(myStack2.getMin());
System.out.println(myStack2.pop());
System.out.println(myStack2.getMin());
}
/**
* 通过一个数据栈和一个最小栈来实现
*
* 数据栈stackData每次压入数据时,最小栈同步压入数据,
* 当压入的数据比stackMin当前的栈顶数据小时,则压入当前要压入的数据,否则不压入stackMin。
*
* 弹出的时候,只有stackData栈顶的值等于stackMin栈顶的值,stackMin才弹出。
*/
public static class MyStack1{
private Stack<Integer> stackData;
private Stack<Integer> stackMin;
public MyStack1() {
this.stackData = new Stack<>();
this.stackMin = new Stack<>();
}
public void push(Integer value){
if (this.stackMin.isEmpty()){
this.stackMin.push(value);
}else if (value <= this.getMin()){
this.stackMin.push(value);
}
this.stackData.push(value);
}
public Integer pop(){
if (this.stackData.isEmpty()){
throw new RuntimeException("stackData is empty");
}
Integer value = this.stackData.pop();
if (value.intValue() == this.getMin().intValue()){
this.stackMin.pop();
}
return value;
}
private Integer getMin() {
if (this.stackMin.isEmpty()){
throw new RuntimeException("stackMin is empty");
}
return this.stackMin.peek();
}
}
/**
* 通过一个数据栈和一个最小栈来实现
* 数据栈stackData每次压入数据时,最小栈同步压入数据,
* 当压入的数据比stackMin当前的栈顶数据大时,则压入stackMin当前的栈顶,否则压入当前要压入的数据,
*
* 弹出的时候同步弹出stackData和stackMin的栈顶。
*
* 相比MyStack1,stackMin占用的空间更大一些
*/
public static class MyStack2{
private Stack<Integer> stackData;
private Stack<Integer> stackMin;
public MyStack2() {
this.stackData = new Stack<>();
this.stackMin = new Stack<>();
}
public void push(Integer value){
if (this.stackMin.isEmpty()){
this.stackMin.push(value);
}else if (value < this.getMin()){
this.stackMin.push(value);
}else{
this.stackMin.push(this.stackMin.peek());
}
this.stackData.push(value);
}
public Integer pop(){
if (this.stackData.isEmpty()){
throw new RuntimeException("stackData is empty");
}
this.stackMin.pop();
return this.stackData.pop();
}
private Integer getMin() {
if (this.stackMin.isEmpty()){
throw new RuntimeException("stackMin is empty");
}
return this.stackMin.peek();
}
}
}