Medium草稿★★★★★O(n) 時間 · O(n) 空間
StackSimulation
Patterns🥞 堆疊🎮 模擬
尚未複習過

解法已隱藏 — 先讀題目敘述、自己想想看,再點上方按鈕揭曉。

946Validate Stack SequencesStackMediumStack

給定兩個整數陣列 pushedpopped,兩者皆為 1n 的排列。判斷這組 push/pop 序列是否為合法的堆疊操作序列。

Example:

Input: pushed = [1,2,3,4,5], popped = [4,5,3,2,1] Output: true

Intuition

TIP

核心思路:模擬堆疊操作,依序 push 元素,每次 push 後持續檢查棧頂是否與 popped 序列的下一個元素相同,若是則 pop。

Approaches

1. In-place: pushed as Stack (O(1) extra) — O(n) / O(1)
  • Idea: 重用 pushed 陣列前段當堆疊,top 當寫入指標,省去額外堆疊
  • Time: O(n)
  • Space: O(1) - 不開額外結構
class Solution {
    fun validateStackSequences(pushed: IntArray, popped: IntArray): Boolean {
        var top = 0   // pushed[0 until top) 當作堆疊
        var j = 0
        for (x in pushed) {
            pushed[top++] = x
            while (top > 0 && pushed[top - 1] == popped[j]) { top--; j++ }
        }
        return top == 0
    }
}
⭐ 2. Stack Simulation (greedy) — O(n) / O(n)
  • Idea: 用一個堆疊模擬操作,遍歷 pushed 陣列依序壓入,每次壓入後用 while 迴圈盡可能 pop,最後檢查堆疊是否為空
  • Time: O(n) - 每個元素最多入棧出棧各一次
  • Space: O(n) - 堆疊最多存 n 個元素
class Solution {
    fun validateStackSequences(pushed: IntArray, popped: IntArray): Boolean {
        val stack = ArrayDeque<Int>()
        var j = 0

        for (x in pushed) {
            stack.addLast(x)
            while (stack.isNotEmpty() && stack.last() == popped[j]) {
                stack.removeLast()
                j++
            }
        }

        return stack.isEmpty()
    }
}

🔑 Takeaways