棧的壓入、彈出序列
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