Leetcode | 155. 最小栈(java实现)

本文介绍了如何设计一个最小栈,该栈支持push、pop、top和getMin操作,并能在常数时间内检索到最小元素。通过分析题目,提出使用两个栈同步操作的解题思路,其中一个栈用于存储最小值。此外,还探讨了一种优化方案,即只在遇到更小值时才更新辅助栈。最后,介绍了一种仅使用一个栈和额外变量的实现方法,利用栈来保存不同最小值阶段的标记。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
 push(x) —— 将元素 x 推入栈中。
 pop() —— 删除栈顶的元素。
 top() —— 获取栈顶元素。
 getMin() —— 检索栈中的最小元素。
示例:
输入:
 [“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.
提示:pop、top 和 getMin 操作总是在 非空栈 上调用。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/min-stack

解题

题目分析

 乍一看这题输入输出没看懂,其实很简单,就是设计一个栈类叫最小栈,和普通栈(java自带的stack类)的区别就在于多了一个可以返回当前栈内最小值的getMin()方法。Stack栈类的其他方法照常可以使用。我们的主要问题就是求解怎么在常数时间检索出当前栈内所有元素的最小值。
 对于一个最小栈minStack来说,题目中要求的四个方法:

  1. 入栈方法:push(x),和Stack类的入栈方法一样,可以直接用stack.push(x)实现
  2. 出栈方法:pop() ,和Stack类的出栈方法一样,可以直接用stack.pop()实现。
  3. 获取栈顶元素方法:top(),Stack类同样有类似的方法peek(),peek()和pop()的去区别在于两者都能返回栈顶元素的值,但是pop()会同时删除栈顶元素,peek()不删。
  4. 检索栈中的最小元素方法:getMin(),只有此方法原本的Stack类中没有,我们需要设计实现。

两个栈实现(创建一个辅助栈存储最小值)

 我们可以在minStack栈内用两个栈来实现存储当前栈内的最小值。
 一个栈stack为普通的栈,依次存储我们压入栈的值。
 另一个栈stackmin和上个栈同等大小,同步上一个栈的所有操作,一一对应,只不过存储的是栈stack中对应元素作为栈顶元素时的当前stack栈内元素的最小值,这个栈作为一个辅助栈。
 如何存储?因为两个栈同步,我们维护一个当前最小值的变量,所以每当stack栈中加入一个元素,与之前维护的最小值变量相比,如果比之前的小就更新最小值变量,如果没之前那个小就维护之前那个值将其压入stackmin栈中。
 这样我们在minStack类中的getMin()方法中只需将当前的minStack栈中的栈顶元素弹出即可。比如示例中输入的意思其实是,先构造一个minStack,然后依次压入push值-2、0、-3,然后获取当前栈内的最小值。当前的两个栈内元素如下图解:(所以当前栈内元素最小值是-3)
 在这里插入图片描述
 然后我们弹出一个栈顶元素的话,两个栈都同步弹出栈顶元素。两个栈更新如下图:(那么此时栈内元素的最小值就变为-2了)
在这里插入图片描述

class MinStack {
   
    public Stack<Integer> stack;
    public Stack<Integer> stackmin;
    /** initialize your data structure here. */
    public MinStack() {
   
        stack = new Stack<>();
        stackmin = new Stack<>();
    }
    
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值