题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
分析
用2个栈,一个栈用来正常存储st1,另一个用来存当前的最小值st2。
逻辑是:如果st2的栈顶大于要进栈的数,就st1、st2都添加;如果st2的栈顶小于这个数,st2就再添加一次自己的栈顶元素
public class Solution {
Stack<Integer> st1=new Stack<Integer>();
Stack<Integer> st2=new Stack<Integer>();
public void push(int node) {
st1.push(node);
if(!st2.empty()){
if(node>st2.peek()){
st2.push(st2.peek());
}else{
st2.push(node);
}
}else{
st2.push(node);
}
}
public void pop() {
if(st1.empty())
throw new RuntimeException("Your stack is empty.");
st2.pop();
st1.pop();
}
public int top() {
if(st1.empty())
throw new RuntimeException("Your stack is empty.");
return st1.peek();
}
public int min() {
if(st1.empty())
throw new RuntimeException("Your stack is empty.");
return st2.peek();
}
}
优化
辅助栈存储的是最小值的索引(这样就不用重复存最小值,只需要存一个索引)
public class MinStack {
private List<Integer> data = new ArrayList<Integer>();
private List<Integer> mins = new ArrayList<Integer>();
public void push(int num) {
data.add(num);
if(mins.size() == 0) {
// 初始化mins
mins.add(0);
} else {
// 辅助栈mins push最小值的索引
int min = getMin();
if (num < min) {
mins.add(data.size() - 1);
}
}
}
public int pop() {
// 栈空,抛出异常
if(data.size() == 0) {
throw new EmptyStackException();
}
// pop时先获取索引
int popIndex = data.size() - 1;
// 获取mins栈顶元素,它是最小值索引
int minIndex = mins.get(mins.size() - 1);
// 如果pop出去的索引就是最小值索引,mins才出栈
if(popIndex == minIndex) {
mins.remove(mins.size() - 1);
}
return data.remove(data.size() - 1);
}
public int getMin() {
// 栈空,抛出异常
if(data.size() == 0) {
throw new EmptyStackException();
}
// 获取mins栈顶元素,它是最小值索引
int minIndex = mins.get(mins.size() - 1);
return data.get(minIndex);
}
}