返回

深入剖析LeetCode 155:揭秘动态规划打造最小栈

闲谈

引言

作为算法修行者,LeetCode 题库无疑是磨炼技艺的宝库。今天,我们聚焦于备受推崇的 155 题——最小栈。本篇博文将结合动态规划的巧妙运用,深入剖析如何构建一个能在常数时间内检索到最小元素的栈。

问题背景

最小栈顾名思义,除了具备普通栈的基本操作(push、pop、top)外,还额外提供了一个在常数时间内返回栈中最小元素的 getMin() 函数。乍看之下,如何在栈这种顺序数据结构中高效获取最小值似乎有些棘手。

动态规划解法

动态规划(DP)是一种用于解决复杂问题的高效技术,通过将问题分解成子问题,并针对每个子问题存储和重用已解决的结果,从而大幅优化求解效率。

在最小栈问题中,我们可以利用 DP 的思想,在每次 push 操作后,同时记录当前栈中最小元素。具体步骤如下:

  1. 初始化: 在创建栈时,将最小元素初始化为栈顶元素。
  2. push: 当 push 一个新元素时,与栈顶元素比较,更新最小元素值。
  3. pop: 当 pop 栈顶元素时,同时检查是否需要更新最小元素值。
  4. getMin: 只需直接返回当前栈中的最小元素值。

实现细节

基于上述思路,我们可以用如下代码实现最小栈:

class MinStack:
    def __init__(self):
        self.stack = []
        self.min_element = None

    def push(self, val):
        if self.stack:
            self.min_element = min(self.min_element, val)
        self.stack.append(val)
        self.min_element = val

    def pop(self):
        if self.stack.pop() == self.min_element:
            self.min_element = min(self.stack) if self.stack else None

    def top(self):
        return self.stack[-1]

    def getMin(self):
        return self.min_element

时间复杂度分析

  • push:O(1)
  • pop:O(1)
  • top:O(1)
  • getMin:O(1)

可见,我们通过动态规划的巧妙运用,实现了所有操作均在常数时间内完成,满足了最小栈题目的要求。

总结

LeetCode 155 最小栈问题看似复杂,但通过动态规划这一利器,我们可以将问题分解为一系列简单子问题,并逐一解决。这种思路不仅适用于该具体问题,更是一种解决算法问题时的通用策略。掌握动态规划技巧,将使你如虎添翼,轻松征服算法难题!