返回

LeetCode每日一题之30. 包含min函数的栈(JAVA版)

前端







## 题目

定义一个能够记录最小元素的栈,并且在 O(1) 时间内完成最小元素的获取。

**示例 1:** 

```java
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
System.out.println(minStack.min());   // 返回 -3
minStack.pop();
System.out.println(minStack.top());      // 返回 0
System.out.println(minStack.min());   // 返回 -2

提示:

  • 各函数的调用总次数不超过20000次。

解题思路

这道题只对时间复杂度有要求,那可以在空间复杂度上放宽。因此,我们可以使用两个栈,栈1正常实现的 push、pop()、top() 等 API。栈2则用于保存栈1中所有元素的最小值。

当我们向栈1中压入一个元素时,如果栈2为空或者栈2栈顶元素大于等于栈1栈顶元素,那么我们将栈1栈顶元素压入栈2。这样一来,栈2中始终保存着栈1中所有元素的最小值。

当我们从栈1中弹出元素时,如果弹出元素等于栈2栈顶元素,那么我们就将栈2栈顶元素也弹出。这样一来,栈2中始终保存着栈1中所有元素的最小值。

当我们查询栈1的最小元素时,直接返回栈2的栈顶元素即可。这样一来,我们可以在 O(1) 时间内完成最小元素的查询。

JAVA代码实现

import java.util.Stack;

class MinStack {

    private Stack<Integer> stack1;
    private Stack<Integer> stack2;

    public MinStack() {
        stack1 = new Stack<>();
        stack2 = new Stack<>();
    }

    public void push(int x) {
        stack1.push(x);
        if (stack2.isEmpty() || stack2.peek() >= x) {
            stack2.push(x);
        }
    }

    public void pop() {
        if (stack1.peek().equals(stack2.peek())) {
            stack2.pop();
        }
        stack1.pop();
    }

    public int top() {
        return stack1.peek();
    }

    public int min() {
        return stack2.peek();
    }
}

复杂度分析

  • 时间复杂度:

    • push()、pop()、top() 和 min() 操作的时间复杂度都是 O(1)。
  • 空间复杂度:

    • 空间复杂度为 O(n),其中 n 为栈中的元素个数。

总结

本题是一道经典的面试题,考察了对栈数据结构的理解和应用能力。通过使用两个栈,我们可以实现一个在 O(1) 时间内完成最小元素查询的栈。