【刷题 issue1】程序员代码面试指南 —— IT 名企算法与数据结构题目最优解

本文介绍了如何设计一个在 O(1) 时间复杂度内实现 pop、push 和 getMin 操作的特殊栈。通过两个栈,stackData 存储数据,stackMin 保存最小值,提供了两种不同的实现策略,分析了它们的优缺点,并给出了相应的 Java 实现。
摘要由CSDN通过智能技术生成

第一章 栈和队列

1.1 设计一个有 getMin 功能的栈

【题目】

实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。

【要求】

  1. pop、push、getMin 操作的时间复杂度都是 O(1)。
  2. 设计的栈类型可以使用现成的栈结构。

【难度】

士 ★☆☆☆

【题解】

数据结构采用两个栈:一个用来保存当前栈中的元素,记为 stackData;另一个栈用于保存每一步操作后栈中元素的最小值,记为 stackMin。实现方式有两种:

第一种方案:

  • 压入数据规则:(假设当前数据为 newNum,先将其压入 stackData,然后判断 stackMin 是否为空)
    • 如果为空,则 newNum 也压入 stackMin;
    • 如果不为空,则比较 newNum 和 stackMin 的栈顶元素 topNum 的大小:
      • 如果 newNum ≤ topNum,则 newNum 也压入 stackMin;
      • 如果 newNum > topNum,则 newNum 不压入 stackMin。
  • 弹出数据规则:
    • 先在 stackData 中弹出栈顶元素,记为 value。然后比较其与当前 stackMin 的栈顶元素 topNum 的大小。
    • 由压入规则可知,stackMin 中的元素从栈底到栈顶逐渐减小,topNum 既是 stackMin 的最小值,也是当前 stackData 中元素的最小值。因此,value 只可能大于或等于 topNum。
      • 当 value = topNum,stackMin 弹出栈顶元素;
      • 当 value > topNum,stackMin 不弹出栈顶元素。
    • 压入操作和弹出操作是对应的。
  • 查询当前栈中的最小值:
    • 由压入规则和弹出规则可知,stackMin 始终记录着 stackData 中的最小值。所以,最小值即为 stackMin 的栈顶元素。

第二种方案:

  • 压入数据规则:(假设当前数据为 newNum,先将其压入 stackData,然后判断 stackMin 是否为空)
    • 如果为空,则 newNum 也压入 stackMin;
    • 如果不为空,则比较 newNum 和 stackMin 的栈顶元素 topNum 的大小:
      • 如果 newNum ≤ topNum,则 newNum 也压入 stackMin;
      • 如果 newNum > topNum,则将 topNum 重复压入 stackdsadaMin。
  • 弹出数据规则:
    • 在 stackData 中弹出数据,同时弹出 stackMin 的栈顶元素。
    • 压入操作和弹出操作是对应的。
  • 查询当前栈中的最小值:
    • 由压入规则和弹出规则可知,stackMin 始终记录着 stackData 中的最小值。所以,最小值即为 stackMin 的栈顶元素。

【分析】

相同点:

  • 方案一和方案二都是用 stackMin 保存着 stackData 每一步的最小值;
  • 所有操作的时间复杂度都是 O(1),空间复杂度都是 O(n)。

不同点:

  • 方案一中 stackMin 压入时稍省空间,但是弹出时稍费时间;
  • 方案二中 stackMin 压入时稍费空间,但是弹出时稍省时间。

【实现】

  • MyStack.java
public interface MyStack {
   

    /**
     * 入栈
     *
     * @param newNum 压入堆栈
     * @throws Exception 栈为空
     */
    void push(int newNum) throws Exception;

    /**
     * 出栈
     *
     * @return 弹出堆栈
     * @throws Exception 栈为空
     */
    int pop() throws Exception;

    /**
     * 获得栈中最小元素
     *
     * @return 栈中最小元素
     * @throws Exception 栈为空
     */
    int getMin() throws Exception;

}
  • AbstractMyStack.java
import java.util.Stack;

public abstract class AbstractMyStack implements MyStack {
   

    protected Stack<Integer> stackData;
    protected Stack
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值