微软面试100题系列---设计包含min函数的栈

来源:互联网 发布:软件模拟技术 编辑:程序博客网 时间:2024/06/05 15:29

题目:设计包含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)

0 0
原创粉丝点击