栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
题解:
我的思路:
中心思想是,按照顺序取出popV中的第一个数字num,并且记下一个popV中的数字num_next,判断num和num_next在pushV中的顺序,num_next只能在num的左面第一个,或者右面
功力不行,实现起来很麻烦
我之前想的是:创建一个空stack,之后每一步都有两种可能,但只能选择其一,一是从pushV中取出数字,压入stack;二是从stack中取出数字。然后记录所有的,从stack中取出数字的顺序,最后判断popV是否在这个顺序列表里,更加麻烦,之后看了评论发现了一种更好的思路。
更好的思路:
先创建一个空栈stack,然后判断popV[0]和pushV[0]是否相等,相等的话,就直接将其从两个列表里取出;如果不相等,那么再判断stack[-1]是否和popV[0]是否相等,相等的话,将其从栈和列表中取出;如果还不相等的话,将pushV[0]入栈
这个相当于是一个相亲过程,pushV是钻石男,popV是钻石女,然后创建一个空的stack是剩男。然后开始相亲,规则是,钻石男依次让排在钻石女首位的挑选,如果钻石女首位对其不满意,即两个数字不相等,就将钻石男压入剩男,即:
elif pushV:
stack.append(pushV.pop(0))
如果钻石女对其满意,即数字相等,则两个人都出列去度蜜月,即:
if pushV and popV[0]==pushV[0]:
popV.pop(0)
pushV.pop(0)
然后让下一个钻石女相亲,首先让其看最后一个进入剩男的是否合适,即:
elif stack and stack[-1]==popV[0]:
stack.pop()
popV.pop(0)
如果最后都没有合适的,就认为失败。
下面是两种思路的代码
# 我的思路
# -*- coding:utf-8 -*-
class Solution:
def IsPopOrder(self, pushV, popV):
# write code here
while popV:
# 依次取出pop的数字
num = popV.pop(0)
# 如果这个数字不在pushV中,就直接返回false
if num not in pushV:
return False
# 找到这个数字在pushV中的索引
index = pushV.index(num)
# 为了防止超出pushV的索引,判断如果索引是0的话有两种可能
if index == 0:
# 第一种可能是 这是最后一个pop的数字
if len(pushV) == 1:
# 如果相等,则返回True
if num == pushV[0]:
return True
# 第二种可能是,这个数字仅仅是在pushV中索引为0,不一定什么时候取出
if popV[0] in pushV[index + 1 : ]:
pushV.pop(index)
else:
return False
# 这个是同样道理,为了防止超出列表索引
elif index+1 == len(pushV):
if popV[0] == pushV[index -1]:
pushV.pop(index)
else:
return False
# 判断,下一个pop的数字,是否在push队列中,排在当前pop的数字的左面一个,或者在其右面即可
elif popV[0] == pushV[index-1] or (popV[0] in pushV[index+1 : ]):
pushV.pop(index)
else:
return False
return True
# 大神版
# -*- coding:utf-8 -*-
class Solution:
def IsPopOrder(self, pushV, popV):
# stack中存入pushV中取出的数据
stack=[]
while popV:
# 如果第一个元素相等,直接都弹出,根本不用压入stack
if pushV and popV[0]==pushV[0]:
popV.pop(0)
pushV.pop(0)
#如果stack的最后一个元素与popV中第一个元素相等,将两个元素都弹出
elif stack and stack[-1]==popV[0]:
stack.pop()
popV.pop(0)
# 如果pushV中有数据,压入stack
elif pushV:
stack.append(pushV.pop(0))
# 上面情况都不满足,直接返回false。
else:
return False
return True