算法(3):包含main函数的栈问题

11 篇文章 0 订阅
2 篇文章 0 订阅

包含main函数的栈问题知识点

设计一个支持 push、pop、top 等操作并且可以在 O(1) 时间内检索出最小元素的堆栈。

该问题要求的时间复杂度是在O(1)内。

如果直接使用一个int变量存储当前的最小值,我们的确可以获得最小值,但是当栈pop()了以后,我们无法获得次小值。我们需要一个数据结构来动态保存每个时刻的最小值,每当push()和pop()的时候,同样更新这个数据结构,而且时间复杂度也是O(1),那么看来需要额外O(n)的空间了。可以选择栈或者一个链表(实质上当作栈使用)。我们使用一个辅助栈来实现,该栈和主栈的大小相同,栈顶存放的是当前栈内的最小值。
即:
定义两个stack,一个为存放最小数的序列的辅助栈。
压栈时,先将元素 x 压入 stack1。然后判断 stack2 的情况:
stack2 栈为空或者栈顶元素大于 x,则将 x 压入 stack2 中。
stack2 栈不为空且栈定元素小于 x,则重复压入栈顶元素。
获取最小元素时,从 stack2 中获取栈顶元素即可。

代码实现:

import java.util.Stack;
public class MinStackDemo {
    /**
     * 压栈时,先将元素 x 压入 stack1。然后判断 stack2 的情况:
     * 	stack2 栈为空或者栈顶元素大于 x,则将 x 压入 stack2 中。
     * 	stack2 栈不为空且栈定元素小于 x,则重复压入栈顶元素。
     * 获取最小元素时,从 stack2 中获取栈顶元素即可。
     */
    private Stack<Integer> myStack1= new Stack<>();
    private Stack<Integer> myStack2= new Stack<>();
    //插入元素
    public void push(int x){
        myStack1.push(x);
        if (myStack2.empty()||myStack2.peek()>x){
            myStack2.push(x);
        }else{
            myStack2.push(myStack2.peek());
        }
    }
    //弹出栈顶元素
    public void pop(){
        myStack1.pop();
        myStack2.pop();
    }
    //取栈顶元素
    public int top(){
        return myStack1.peek();
    }
    //取最小值
    public int min(){
        return myStack2.peek();
    }
}


public static void main(String[] args) {
        MinStackDemo minStackDemo = new MinStackDemo();
        minStackDemo.push(1);
        minStackDemo.push(3);
        minStackDemo.push(1);
        minStackDemo.push(4);
        minStackDemo.push(5);
        minStackDemo.push(2);
        minStackDemo.push(0);
        minStackDemo.pop();
        int top = minStackDemo.top();
        int min = minStackDemo.min();
        System.out.println("top="+top+",min="+min);
    }
//结果:top=2,min=1

使用assert断言的方法进行逻辑判断的代码实现:

import java.util.Stack;
public class MinStackDemo{
    Stack<Integer> myStack1 = new Stack<Integer>();
    Stack<Integer> myStack2 = new Stack<Integer>();
    public void push(int item){
        myStack1.push(item);
        if(myStack2.isEmpty()){
            myStack2.push(item);
        }else {
            myStack2.push(myStack2.peek() < item ? myStack2.peek() : item);
        }
    }
    public int pop(){
        assert(myStack1.size()>0 && myStack2.size()>0);
        myStack2.pop();
        return myStack1.pop();
    }
    public int top(){
        return myStack1.peek();
    }
    public int min(){
        assert(myStack1.size()>0 && myStack2.size()>0);
        return myStack2.peek();
    }
}

上面两种写法:时间复杂度:O(1)、空间复杂度:O(n)。

后续如有更优的方法,会继续补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值