《剑指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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章