LeetCode 155. 最小栈

题目:

https://leetcode-cn.com/problems/min-stack/

 

本题难点在于 getMin(),如何快速找到当前栈中最小元素,如果每次在调用 getMin() 的时候才去寻找,时间复杂度较高,所以思考的方向应该是在 push() 和 pop() 时候就去计算最小值并记录。

题解一:

借助辅助栈,我们向目标栈中 push 一个元素时,向辅助栈中 push  min(当前目标栈中最小值, 入栈元素),这样辅助栈顶元素就是目标栈最小值,目标栈 pop 元素时,辅助栈也同样 pop 元素。

class MinStack {

    private static Stack<Integer> stack;
    private static Stack<Integer> minStack;

    /** initialize your data structure here. */
    public MinStack() {
        stack = new Stack();
        minStack = new Stack<>();
    }
    
    public void push(int val) {
        stack.push(val);
        if (minStack.isEmpty()) {
            minStack.push(val);
        } else {
            minStack.push(Math.min(minStack.peek(), val));
        }
    }
    
    public void pop() {
        stack.pop();
        minStack.pop();
    }
    
    public int top() {
        return stack.peek();
    }
    
    public int getMin() {
        return minStack.peek();
    }
}

时间复杂度:O(1).

空间复杂度:O(N).

 

题解二:

我们把"竖"着的栈,看作"横"着的链表,栈中的一个元素看做成链表中的一个节点,每个节点保存当前节点值、最小值以及上一节点指针。

 

class MinStack {
    private Node node;

    /** initialize your data structure here. */
    public MinStack() {}
    
    public void push(int val) {
        if (node == null) {
            node = new Node(val, val);
        } else {
            Node newNode = new Node(val, Math.min(node.minValue, val));
            newNode.prevNone = node;
            node = newNode;
        }
    }
    
    public void pop() {
        node = node.prevNone;
    }
    
    public int top() {
        return node.value;
    }
    
    public int getMin() {
        return node.minValue;
    }

    private class Node {
        int value;
        int minValue;
        Node prevNone;

        public Node(int value, int minValue) {
            this.value = value;
            this.minValue = minValue;
        }
    }
}

node 表示链表的头节点,在push的时候需要更新头节点,在pop时需要删除当前头节点使上一节点变为新的头节点。

时间复杂度:O(1).

空间复杂度:O(N).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值