力扣经典150题第五十四题:最小栈

简介: 力扣经典150题第五十四题:最小栈

题目描述和要求

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

实现 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.

解题思路

我们可以设计一个辅助栈来存储当前栈中的最小元素。在每次 push 操作时,将当前元素与辅助栈的栈顶元素比较,将较小的元素入栈。这样,在 getMin 操作时,只需要返回辅助栈的栈顶元素即可。

算法实现

import java.util.Stack;
public class MinStack {
    Stack<Integer> stack;
    Stack<Integer> minStack;
    public MinStack() {
        stack = new Stack<>();
        minStack = new Stack<>();
    }
    public void push(int val) {
        stack.push(val);
        if (minStack.isEmpty() || val <= minStack.peek()) {
            minStack.push(val);
        }
    }
    public void pop() {
        if (stack.peek().equals(minStack.peek())) {
            minStack.pop();
        }
        stack.pop();
    }
    public int top() {
        return stack.peek();
    }
    public int getMin() {
        return minStack.peek();
    }
}

复杂度分析

  • 时间复杂度:对于每个操作,时间复杂度都是 O(1)。
  • 空间复杂度:额外使用了两个辅助栈,空间复杂度为 O(n),其中 n 为元素数量。

测试和验证

编写测试用例对算法进行验证,确保其正确性和健壮性。

public class Main {
    public static void main(String[] args) {
        MinStack minStack = new MinStack();
        minStack.push(-2);
        minStack.push(0);
        minStack.push(-3);
        System.out.println(minStack.getMin()); // -3
        minStack.pop();
        System.out.println(minStack.top()); // 0
        System.out.println(minStack.getMin()); // -2
    }
}

总结和拓展

本题通过设计一个辅助栈来实现在常数时间内检索到最小元素的要求,实现了一个最小栈的数据结构。这个算法思路清晰简单,在处理类似问题时是一个不错的选择。

除了当前算法,我们也可以考虑其他实现方式,例如使用双端队列、优先队列等方法来解决类似问题。

参考资料

  • 《力扣经典150题》
  • LeetCode 官方网站
相关文章
|
2月前
|
Go C++
【力扣】2696. 删除子串后的字符串最小长度(模拟 栈 C++ Go实现栈)
【2月更文挑战第18天】2696. 删除子串后的字符串最小长度(模拟 栈 C++ Go实现栈)
41 6
|
2月前
LeetCode 热题100——单调栈
LeetCode 热题100——单调栈
24 0
|
2月前
【Leetcode 2487】从链表中移除节点 —— 单调栈
解题思路:维持一个单调递增栈,当栈为空时,记录当前节点为头节点;否则当前节点为栈顶节点的后继节点
|
2月前
【Leetcode 1944】队列中可以看到的人数 —— 单调栈
解题思路:维持一个单调递增栈来辅助计算每个人能够看到的人数。从右往左遍历数组,对于每个人,我们将其身高与栈顶元素的身高进行比较。如果当前人的身高比栈顶元素的身高高,则栈顶元素无法被当前人看到,将其出栈,并累计计数
|
4天前
|
存储 算法 索引
力扣每日一题 6/24 模拟 数组 单调栈
力扣每日一题 6/24 模拟 数组 单调栈
6 0
LeetCode | 232. 用栈实现队列
LeetCode | 232. 用栈实现队列
|
18天前
|
存储 算法 Python
二刷力扣--栈和队列
二刷力扣--栈和队列
|
22天前
|
存储 算法 数据可视化
力扣155题最全解法:如何实现支持常数时间获取最小值的最小栈(附详细图解和复杂度分析)
力扣155题最全解法:如何实现支持常数时间获取最小值的最小栈(附详细图解和复杂度分析)
|
19天前
|
容器
【LeetCode刷题】栈和队列题目练习~
【LeetCode刷题】栈和队列题目练习~
|
22天前
|
存储 SQL 算法
LeetCode题目100:递归、迭代、dfs使用栈多种算法图解相同的树
LeetCode题目100:递归、迭代、dfs使用栈多种算法图解相同的树