《劍指offer》第21題:棧的壓入、彈出序列

21 棧的壓入、彈出序列

  輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否可能爲該棧的彈出順序。
假設壓入棧的所有數字均不相等。例如序列1,2,3,4,5是某棧的壓入順序,序列4,5,3,2,1是該壓棧序列對應
的一個彈出序列,但4,3,5,1,2就不可能是該壓棧序列的彈出序列。(注意:這兩個序列的長度是相等的)

思考:考察棧的棧的特性:後入先出
有一個最笨的方法就是列舉出所有的出棧入棧順序
入棧元素:1,2
  出棧順序可能是[1,2],[2,1]
入棧元素:1,2,3
  出棧順序可能是[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,2,1] 唯一不可能存在的情況[3,1,2]
入棧元素:1,2,3,4
  出棧順序:[1,2,3,4],[1,2,4,3],[1,3,2,4],[1,3,4,2],[1,4,3,2] 不可能存在[1,4,2,3]
   [2,1,3,4],[2,1,4,3],[2,3,1,4],[2,3,4,1],[2,4,3,1] 不可能存在[2,4,1,3]
   [3,2,1,4],[3,2,4,1],[3,4,2,1] 不可能存在[3,1…] 和 [3,4,1,2]
   [4,3,2,1] 不可能存在其他情況

依次類推

方法一: 輔助棧

輔助棧,按順序往棧裏塞元素,遇到和彈出序列元素一樣的則出棧,最後檢查輔助棧是否爲空即可
拿入棧序列 [1,2,3]來說,出棧序列 [3,1,2]
第一步:
1入輔助棧,1 ≠ 3,之後輔助棧不操作
2入輔助棧,2 ≠ 3,之後輔助棧不操作
3入輔助棧,3 == 3,輔助棧和彈出棧該元素同時出棧
第二步:
此時: 輔助棧[1,2] 彈出棧[1,2]
從第一個元素循環彈出棧,和輔助棧最後一個元素對比(重複利用棧的後入先出原理)
1 ≠ 2,彈出棧刪除1,輔助棧不操作,
2 == 2,彈出棧刪除2,輔助棧刪除2
最後輔助棧不爲空,說明不是該壓棧序列的彈出序列,

class Solution1:
    def IsPopOrder(self, pushV, popV):
        # write code here
        if len(pushV) != len(popV):#元素個數不一樣
            return False
        assist = []#輔助棧
        for i in pushV:#遍歷壓入棧,符合的最終存放輔助棧
            assist.append(i)
            if i == popV[0]:
                assist.pop(-1)
                popV.pop(0)

        while len(popV) > 0:#遍歷彈出棧
            if popV[0] == assist[-1]:
                assist.pop(-1)
            popV.pop(0)

        return True if len(assist)== 0 else False

方法二:簡化版

class Solution2:
    def IsPopOrder(self, pushV, popV):
        # write code here
        if len(pushV) != len(popV):
            return False

        assist = []
        for i in pushV:
            assist.append(i)
            while len(assist) and assist[-1] == popV[0]:
                assist.pop()
                popV.pop(0)

        return True if len(assist) == 0 else False
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章