题目
实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作 ,要求:
1、push,pop,getMin操作的时间复杂度都是O(1)
2、设计的栈类型可以使用现成的栈结构
用栈实现
//用两个栈,一个用来放数据,一个存放当前数据的最小值
//一个数据newNum进入data栈,判断newNum与min栈顶元素newMin(即最小值)的大小,
//若newNum<=newMin,则将newNum压入min,否则,将newMin压入min
public static class MyStack1{
private Stack<Integer> data;
private Stack<Integer> min;//辅助栈,用来存放每一次当前栈的最小值
public MyStack1(){
this.data = new Stack<Integer>();
this.min = new Stack<Integer>();
}
public void push(int newNum){
if(this.min.isEmpty()){
this.min.push(newNum);//初始化
}else if(newNum <= this.getMin()){
this.min.push(newNum);
}else{
int newMin = this.min.peek();
this.min.push(newMin);
}
this.data.push(newNum);
}
public int pop(){
if(this.data.isEmpty()){
throw new IllegalArgumentException("栈已空!");
}
this.min.pop();
return this.data.pop();
}
public int getMin(){
if(this.min.isEmpty()){
throw new IllegalArgumentException("栈已空!");
}
return this.min.peek();
}
}
改进版,用链表实现(也可用栈)
//改进,min栈存最小值的索引
/*mins栈中改存最小值在data数组中的索引。这样一来,当push了与最小值相同元素的时候,就不需要动mins栈了。
而pop的时候,pop出的元素的索引如果不是mins栈顶元素,mins也不出栈。同时,获取最小值的时候,需要拿到mins栈顶元素作为索引,
再去data数组中找到相应的数作为最小值。*/
public static class MyStack2{
private List<Integer> data = new ArrayList<Integer>();
private List<Integer> mins = new ArrayList<Integer>();
public void push(int num){
if(mins.size() == 0){
mins.add(0);//初始化min
}else{
int min = getMin();
if(num < min){// 辅助栈mins push最小值的索引
mins.add(data.size() - 1);
}
}
}
public int pop(){
if(data.size() == 0){
throw new IllegalArgumentException("栈已空!");
}
// 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(mins.size() == 0){
throw new IllegalArgumentException("栈已空!");
}
// 获取mins栈顶元素,它是最小值索引
int minIndex = mins.get(mins.size() - 1);
return data.get(minIndex);
}
}