LeetCode: 155. 最小栈

95 阅读2分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

155. 最小栈

来源:力扣(LeetCode)

链接: leetcode.cn/problems/mi…

设计一个支持 pushpoptop 操作,并能在常数时间内检索到最小元素的栈。

实现 MinStack 类:

  • MinStack() 初始化堆栈对象。
  • void push(int val) 将元素val推入堆栈。
  • void pop() 删除堆栈顶部的元素。
  • int top() 获取堆栈顶部的元素。
  • int getMin() 获取堆栈中的最小元素。

示例 1:

输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]

输出:
[null,null,null,null,-3,null,0,-2]

解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.

提示:

  • 231-2^{31} <= val <= 23112^{31} - 1
  • pop、top 和 getMin 操作总是在 非空栈 上调用
  • push, pop, top, and getMin最多被调用 31043 * 10^4

解法

对于这类题目一般是使用辅助栈,类似的题目有用两个栈实现队列,只用队列实现栈,顺序倒一遍,都是需要使用辅助栈或者队列;

  • 辅助栈:一个栈正常放元素,一个辅助栈放最小元素,每次新元素都与辅助栈栈顶元素进行比较,如果小于该栈顶,则入栈;如果大于该栈顶,则将栈顶元素复制一遍; 在这里插入图片描述
  • 链表结构体:栈是需要连续数组的,链表是可以有多重属性的,也能保持前后位置关系;适用一个单链表结构题,属性有该节点的值,该节点的最小值,该节点的下一个节点;由于栈是先入后出,那么后入的节点的下一节点就是之前的节点;

代码实现

辅助栈

python实现

class MinStack:

    def __init__(self):
        self.data = []
        self.helper = []

    def push(self, val: int) -> None:
        self.data.append(val)
        if len(self.helper) == 0 or val <= self.helper[-1]:
            self.helper.append(val)
        else:
            self.helper.append(self.helper[-1])

    def pop(self) -> None:
        if self.data:
            self.helper.pop()
            self.data.pop()

    def top(self) -> int:
        return self.data[-1] if self.data else -1

    def getMin(self) -> int:
        return self.helper[-1] if self.helper else -1


# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(val)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()

c++实现

class MinStack {
    vector <int> data;
    vector <int> helper;
public:
    MinStack() {

    }
    
    void push(int val) {
        data.push_back(val);
        if (helper.empty() || helper.back() > val)
            helper.push_back(val);
        else
            helper.push_back(helper.back());
    }
    
    void pop() {
        if (!data.empty()) {
            data.pop_back();
            helper.pop_back();
        }
    }
    
    int top() {
        return !data.empty() ? data.back() : -1;
    }
    
    int getMin() {
        return !helper.empty() ? helper.back() : -1;
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(val);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

复杂度分析

  • 时间复杂度: O(n)O(n)
  • 空间复杂度: O(n)O(n)

链表结构

python实现

class ListNode:
    def __init__(self, val=None, min_val=None, next_node=None):
        self.val = val
        self.min = min_val
        self.next = next_node

class MinStack:
    def __init__(self):
        self.node = ListNode()

    def push(self, val: int) -> None:
        if not self.node or self.node.val == None:  # 进行node判断,是否为None(原因是pop可能到最后节点为None,或者是初始化的节点)
            self.node = ListNode(val, val)
        else:
            self.node = ListNode(val, min(self.node.min, val), self.node)

    def pop(self) -> None:
        self.node = self.node.next

    def top(self) -> int:
        return self.node.val

    def getMin(self) -> int:
        return self.node.min

# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(val)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()

c++实现

class MinStack {
public:

    struct Node {
        int val, mn;
        Node* next;
        Node(int _val, int _min, Node* _next=NULL) {
            val = _val;
            mn = _min;
            next = _next;
        }
    } *head;
    
    void push(int val) {
        if (!head)
            head = new Node(val, val);
        else
            head = new Node(val, min(val, head->mn), head);
    }
    
    void pop() {
        if (!head) return;
        Node* tmp = head;
        head = head->next;
        delete(tmp);
    }
    
    int top() {
        if(!head) return -1;
        return head->val;
    }
    
    int getMin() {
        if(!head) return -1;
        return head->mn;
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(val);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

复杂度分析

  • 时间复杂度: O(n)O(n)
  • 空间复杂度: O(n)O(n)