1、题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))
2、算法分析
① 题目要求构造栈的相关函数,然后求使用栈求最小值,可以定义两个栈,一个栈保存当前栈的元素,就是一个正常的栈,记为stackData;另一个栈用于保存入栈元素每一步比较的最小值,这个栈记为stackMin。
② 压栈数据规则(push): 假设当前数据为node,先将其压入stackData,然后判断stackMin栈是否为空;如果为空,将node也压入stackMin中;如果不为空,比较node和stackMin的栈顶元素哪一个更小;如果node元素更小,或者两者相等,则node元素也压入stackMin中;如果stackMin中的栈顶元素更小,则stackMin不压入任何内容。以上情况都不满足的话,将此元素压入stackData中。
③ 弹出数据规则(pop):先在stackData中弹出栈顶元素,记为value,比较当前value和stackMin栈顶元素哪一个最小值,stackMin中存在的元素是从栈底到栈顶依次逐渐变小的,stackMin栈顶元素既是stackMin的最小值,也是当前stackData栈中元素的最小值,stackMin始终记录着stackData中的最小值。
总而言之,就是stackMin进栈的时候进的是比相邻栈顶元素小的,stackMin出栈也是最小的元素。peek就是返回stackMin的栈顶元素的。stackMin始终记录着stackData中的最小值。
知识补充:
1. Stack.peek():
peek()函数返回栈顶的元素,但不弹出该栈顶元素。
2. Stack.pop():
pop()函数返回栈顶的元素,并且将该栈顶元素出栈。
3、算法实现
import java.util.Stack;
/*
代码分为3部分:实现基本栈的功能:包括 进栈 出栈 获取最小值
*/
public class Solution {
/*
定义两个栈,一个栈是存储的是当前栈的元素,另一个栈存储的是保存最小值的元素
*/
private Stack<Integer> stackData;
private Stack<Integer> stackMin;
// 构造方法实例化两个栈
public Solution(){
this.stackData = new Stack<Integer>();
this.stackMin = new Stack<Integer>();
}
// 入栈:主要判断原栈元素进入stackMin的较小值
public void push(int node) {
// 如果保存的最小元素的栈已经是空的,就把结点放进去
if(this.stackMin.isEmpty()){
this.stackMin.push(node);
}else if(node < this.min()){
this.stackMin.push(node);
}
// 要不然 当前进栈的元素是大的元素,放入stackData中
this.stackData.push(node);
}
//出栈
public int pop() {
if(this.stackData.isEmpty()){
throw new RuntimeException("Your stack is empty");
}
// 出栈
int value = this.stackData.pop();
if(value == this.min()){
this.stackMin.pop();
}
return value;
}
public int min() {
if(this.stackMin.isEmpty()){
throw new RuntimeException("Your stack is empty");
}
// 要不然就返回stackMin的栈顶元素
return this.stackMin.peek();
}
}