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

题目:设计包含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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值