【LeetCode】155. 最小栈

leetcode

 

解题思路

最小栈问题的核心在于维护当前栈中的最小值,并要求所有操作的时间复杂度为 O(1),最常用的方法是双栈法,即使用一个数据栈存储元素,另一个辅助栈动态存储当前栈的最小值。以下是具体实现步骤:


关键设计

  1. 数据栈(data)​:用于正常存储所有元素。
  2. 最小值栈(minStack)​:栈顶始终保存当前数据栈中的最小值。
    • Push 操作:将新元素压入数据栈,同时比较新元素与 minStack 的栈顶元素,将较小值压入 minStack
    • Pop 操作:同时弹出数据栈和最小值栈的栈顶元素。
    • GetMin 操作:直接返回 minStack 的栈顶元素。

Golang代码实现

type MinStack struct {
    data    []int   // 数据栈
    minStack []int  // 最小值栈
}

func Constructor() MinStack {
    return MinStack{
        data:    make([]int, 0),
        minStack: []int{math.MaxInt32}, // 初始化为极大值,避免空栈判断
    }
}

func (this *MinStack) Push(val int) {
    this.data = append(this.data, val)
    // 计算当前最小值(新值与 minStack 栈顶的较小者)
    currentMin := min(val, this.minStack[len(this.minStack)-1])
    this.minStack = append(this.minStack, currentMin)
}

func (this *MinStack) Pop() {
    this.data = this.data[:len(this.data)-1]
    this.minStack = this.minStack[:len(this.minStack)-1]
}

func (this *MinStack) Top() int {
    return this.data[len(this.data)-1]
}

func (this *MinStack) GetMin() int {
    return this.minStack[len(this.minStack)-1]
}

// 辅助函数:取较小值
func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}

复杂度分析

指标说明
时间复杂度 O(1) 所有操作(Push/Pop/Top/GetMin)均为常数时间
空间复杂度 O(n) 需要两个栈存储元素,最坏情况下每个栈存储 n 个元素

代码解析

  1. 初始化
    • minStack 初始时压入一个极大值 math.MaxInt32,避免空栈判断,简化逻辑。
  2. Push 操作
    • 将新元素 val 压入 data 栈。
    • 比较 val 与 minStack 的当前栈顶,将较小者压入 minStack,确保其栈顶始终为当前最小值。
  3. Pop 操作
    • 同步弹出 data 和 minStack 的栈顶元素。
  4. GetMin 逻辑
    • 直接返回 minStack 的栈顶值,无需遍历数据栈。

示例验证

func main() {
    obj := Constructor()
    obj.Push(-2)
    obj.Push(0)
    obj.Push(-3)
    fmt.Println("当前最小值:", obj.GetMin()) // 输出: -3
    obj.Pop()
    fmt.Println("栈顶元素:", obj.Top())     // 输出: 0
    fmt.Println("当前最小值:", obj.GetMin()) // 输出: -2
}

其他解法对比

  1. 链表法(空间优化)​
    • 每个节点记录当前最小值,通过链表指针维护顺序。
    • 优点:无需额外栈,空间复杂度更优(但仍为 O(n))。
    • 缺点:实现复杂,代码可读性差。
  2. 差值存储法
    • 存储元素与当前最小值的差值,通过差值计算实际值。
    • 优点:仅用一个栈。
    • 缺点:涉及长整型转换,容易溢出。

总结

双栈法通过同步维护数据栈和最小值栈,以简洁的逻辑实现了所有操作的 O(1) 时间复杂度,是工程实现和面试中的标准解法。该方案在代码可读性、时间效率和空间复杂度之间取得了平衡。

posted @ 2025-03-30 15:09  云隙之间  阅读(77)  评论(0)    收藏  举报