返回

精辟剖析:剑指Offer 30 —— 最小值栈

后端

导语:

剑指Offer是程序员面试的经典题库,其中第30题是一个颇具挑战性的问题,它要求我们设计并实现一个包含min函数的栈数据结构,使得该栈在执行push、pop和min操作时的时间复杂度均为O(1)。在本文中,我们将对这一算法问题进行详细的剖析,并提供一份完整的代码示例供您参考。

问题陈述:

定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。 此栈包含的方法有:

  • push(value):将value压入栈中。
  • pop():从栈顶弹出一个元素。
  • min():获取栈中所含最小元素。

算法设计:

为了满足时间复杂度的要求,我们需要一种巧妙的方法来保存栈中最小元素的信息。一种常见的设计思路是使用两个栈:

  • 主栈:用于存储元素的实际值。
  • 辅助栈:用于存储最小元素的值。

当我们向主栈中压入一个元素时,我们同时也会将其压入辅助栈,但仅当该元素小于或等于辅助栈栈顶元素时,才会执行此操作。这样,辅助栈始终包含栈中所有元素的最小值。

当我们从主栈中弹出一个元素时,我们同时也会从辅助栈中弹出一个元素,以确保两者的同步。

当我们调用min函数时,我们只需返回辅助栈的栈顶元素即可。

代码示例:

class MinStack:
    def __init__(self):
        self.main_stack = []
        self.min_stack = []

    def push(self, value):
        self.main_stack.append(value)
        if not self.min_stack or value <= self.min_stack[-1]:
            self.min_stack.append(value)

    def pop(self):
        if self.main_stack[-1] == self.min_stack[-1]:
            self.min_stack.pop()
        self.main_stack.pop()

    def min(self):
        return self.min_stack[-1]

算法分析:

  • 时间复杂度:

    • push操作:O(1)
    • pop操作:O(1)
    • min操作:O(1)
  • 空间复杂度:

    • 主栈:O(n),其中n是栈中元素的数量。
    • 辅助栈:O(n),其中n是栈中最小元素的数量。

结语:

剑指Offer 30是一个极具挑战性的算法问题,但通过巧妙的设计和实现,我们能够在满足时间复杂度要求的前提下解决它。希望本文对您的理解和学习有所帮助。如果您有任何问题或建议,欢迎随时留言。