题目:设计包含min函数的栈
定义一个栈结构,要求添加一个min函数,得到栈的最小元素;
要求:min函数,push函数,pop函数的时间复杂度为o(1)
实现
方法1
思路:除了题目中要求的栈之外,再创建一个栈(最小栈),用来记录最小值,每当在原栈中push元素时,与最小栈的栈顶元素比较,如果push的值小,则push到最小栈中;否则,将最小栈的栈顶元素再次push到最小栈中;
实现代码:
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class Num2 {
/*
* get the min of stack
*/
public static void main(String[] args) {
MinStack stack=new MinStack();
stack.push(10);
stack.push(2);
stack.push(5);
stack.push(8);
stack.push(11);
System.out.println(stack.min());
stack.pop();
System.out.println(stack.min());
stack.push(1);
System.out.println(stack.min());
}
}
class MinStack{
List <Integer>data=new ArrayList<Integer>();
List<Integer> min=new ArrayList<Integer>();
public void push(int value){
data.add(value);
if(min.size()==0){
min.add(value);
return;
}
int minTop=min.get(min.size()-1);
if(minTop>value){
min.add(value);
}else{
min.add(minTop);
}
}
public void pop(){
min.remove(min.size()-1);
data.remove(data.size()-1);
}
public int min(){
return min.get(min.size()-1);
}
}
这种方法,空间复杂度o(n)
方法2
思路:
方法1中空间复杂度大,对方法1优化;
一般来说,最小值不会每次都需要更新,因此方法1中的最小值栈中的很多元素是重复的;
优化:向原栈中push新元素时,只有当新元素<=最小栈的栈顶,才向最小栈中push;从原栈中pop时,pop的值等于最小值时,才从最小栈中pop;其他时候不对最小栈pop;
该方法是对方法1中的空间的优化;但空间复杂度仍不是o(1)
实现:
import java.util.ArrayList;
import java.util.List;
public class Num2_2 {
public static void main(String[] args) {
MinStack_2 stack=new MinStack_2();
stack.push(10);
stack.push(2);
stack.push(5);
stack.push(8);
stack.push(11);
System.out.println(stack.min());
stack.pop();
System.out.println(stack.min());
stack.push(1);
System.out.println(stack.min());
}
}
class MinStack_2{
List <Integer>data=new ArrayList<Integer>();
List<Integer> min=new ArrayList<Integer>();
public void push(int value){
data.add(value);
if(min.size()==0){
min.add(value);
return;
}
int minTop=min.get(min.size()-1);
if(minTop>value){
min.add(value);
}
}
public void pop(){
int topNum=data.get(data.size()-1);
if(topNum==min()){
min.remove(min.size()-1);
}
}
public int min(){
if(min.size()==0){
return Integer.MAX_VALUE;
}
return min.get(min.size()-1);
}
}
方法3
思路:
需要而外一个变量用来保存当前的最小值min;
因为栈中所有元素的值都不会小于当其为栈顶元素时min函数的值,所以在栈中不保存原数据,而是保存原数据比相应最小值大出来的值即可,比如对于元素5,如果以5为栈顶的最小值为3,则push(5)时不是直接存储5,而是存储2(5-3);
对于最小值更新的位置,栈中应该存储0,但是我们不存储0,而是利用该位置存储–前一个最小值与当前的值的差值;
代码实现:
import java.util.ArrayList;
import java.util.List;
public class Num2_3{
public static void main(String[] args) {
MinStack_3 stack=new MinStack_3();
stack.push(10);
stack.push(2);
stack.push(5);
stack.push(8);
stack.push(11);
System.out.println(stack.min());
stack.pop();
System.out.println(stack.min());
stack.push(1);
System.out.println(stack.min());
}
}
class MinStack_3{
List <Integer>data=new ArrayList<Integer>();
int min=Integer.MAX_VALUE;
public void push(int value){
if(value<this.min){
data.add(min-value);
this.min=value;
}else{
data.add(value-min);
}
}
public int pop(){
int top=data.get(data.size()-1);
if(top>0){
return top+this.min;
}
this.min=this.min-top;
return this.min;
}
public int min(){
return this.min;
}
}
该方法空间复杂度:o(1)