1. 程式人生 > 其它 >程式設計師面試金典 - 面試題 03.02. 棧的最小值

程式設計師面試金典 - 面試題 03.02. 棧的最小值

技術標籤:Leetcode演算法資料結構leetcode

題目難度: 簡單

原題連結

今天繼續更新程式設計師面試金典系列, 大家在公眾號 演算法精選 裡回覆 面試金典 就能看到該系列當前連載的所有文章了, 記得關注哦~

題目描述

請設計一個棧,除了常規棧支援的 pop 與 push 函式以外,還支援 min 函式,該函式返回棧元素中的最小值。執行 push、pop 和 min 操作的時間複雜度必須為 O(1)。

示例:

  • MinStack minStack = new MinStack();
  • minStack.push(-2);
  • minStack.push(0);
  • minStack.push(-3);
  • minStack.getMin(); --> 返回 -3.
  • minStack.pop();
  • minStack.top(); --> 返回 0.
  • minStack.getMin(); --> 返回 -2.

題目思考

  1. 內部需要什麼資料結構來滿足所有操作都是 O(1), 一個棧夠嗎?

解決方案

思路

  • 要使得 push 和 pop 的複雜度為 O(1), 傳統的棧就可以搞定, 難點在於如何使得 min 函式也為 O(1)
  • 如果我們能一直維護當前所有元素的最小值, 那麼 min 函式直接返回它就可以, 但問題是在 pop 的時候有可能會正好 pop 這個最小值, pop 之後的最小值(也即原來的次小值)如何得到呢?
  • 要儲存多個最小值, 顯然一個變數不夠用. 而根據上一步的分析, 這裡我們可以考慮額外引入一個單調遞減棧, 棧頂存當前最小值, 下面依次是次小, 第三小…
  • 這樣如果 pop 了最小值的話, 這個單調棧的棧頂仍會儲存 pop 後的最小值, 每次 min 只需要取這個棧的棧頂即可
  • 而 push 的時候也需要額外的操作, 由於是單調棧, 只需要在新的值小於等於棧頂的時候才 push 到單調棧中.特別注意在等於棧頂的時候也要 push 到單調棧中, 這是因為如果對於重複的最小值 x 不 push, 那麼在後續的 pop 其中一個 x 之後, 棧頂(不再是 x)就和實際最小值(仍為 x)不一致了

複雜度

  • 時間複雜度 O(1)
    • 各種操作都是常數複雜度
  • 空間複雜度 O(N)
    • 使用了兩個棧

程式碼

class MinStack:
    def __init__(self):
        """
        initialize your data structure here.
        """
        # 一個普通棧和一個單調遞減棧
        self.minstack = []
        self.stack = []

    def push(self, x: int) -> None:
        self.stack.append(x)
        if not self.minstack or x <= self.minstack[-1]:
            # 如果單調棧頂為空或者當前新值小於等於單調棧頂才push
            # 注意這裡等於也需要push. 如果對於重複的最小值 x 不 push, 那麼在後續的 pop 其中一個 x 之後, 棧頂(不再是 x)就和實際最小值(仍為 x)不一致了
            self.minstack.append(x)

    def pop(self) -> None:
        if not self.stack:
            return
        x = self.stack.pop()
        if x == self.minstack[-1]:
            # 如果單調棧頂恰好等於pop的值, 也要pop單調棧
            self.minstack.pop()

    def top(self) -> int:
        if not self.stack:
            return -1
        return self.stack[-1]

    def getMin(self) -> int:
        if not self.minstack:
            return -1
        return self.minstack[-1]

大家可以在下面這些地方找到我~