题目描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
知识点
栈
Qiang的思路
对于一个栈,当压入序列确定时,当给出第一个弹出元素,就会将压入序列分成两段,对于前半段的元素必须先弹出后面的,因为此时前半段全被压入栈中,但是后半段元素可以任意弹出,因为后半段的压入情况不确定。然后对于第二个弹出元素时,我们需要从上一时刻的位置往后遍历,如果遇到相同的那就是这个元素弹出了 ,如果没有那么需要往前遍历。在往前遍历时,如果遇到的第一个未弹出元素和当前弹出元素相等,那么就是这个元素需要弹出,如果不相等那么这个弹出序列并不是压入序列的弹出序列。
# -*- coding:utf-8 -*-
class Solution:
def IsPopOrder(self, pushV, popV):
# write code here
if len(popV)==0:
return True
pos=-1
for j in range(len(popV)):
flag=False
for i in range(pos+1, len(popV)):
if pushV[i]==popV[j]:
pushV[i]=None
pos=i
flag=True
break
if flag==True:
continue
for i in range(pos-1,-1,-1):
if pushV[i]==popV[j]:
pushV[i]=None
pos=i
flag=True
break
if pushV[i]!=None:
return False
if flag==False:
return False
return True
首先需要从上一时刻找到弹出元素的位置出发,往后找,如果找到了弹出元素,则记录该位置,并开始下一轮寻找。如果没有找到,那么需要往前找,但是往前找的时候不用考虑之前弹出的元素,只需要关注第一个未被弹出的元素,如果他和当前弹出的元素相等则继续下一轮寻找,如果不相等则说明不是弹出序列。
同时,需要注意,可能当前弹出元素都不在压入序列中,所以如果查找了一遍并没有发现弹出元素,那么我们可以提前终止遍历,弹出序列一定不是压入序列的弹出结果。
Book中的思路
书中引入了辅助栈的概念,增加是空间复杂度,但是不需要往前遍历,只需要看栈顶元素即可,但是往后遍历还是需要的,所以在一定的程度上降低了时间复杂度。
# -*- coding:utf-8 -*-
class Solution:
def IsPopOrder(self, pushV, popV):
# write code here
s=[]
while popV!=[]:
c=popV.pop(0)
if s!=[] and s[-1]==c:
s.pop(-1)
continue
flag=False
while pushV!=[]:
_c=pushV.pop(0)
if c==_c:
flag=True
break
s.append(_c)
if flag==False:
return False
return True
每次需要先查看辅助栈的栈顶元素,如果栈顶元素等于当前的弹出元素,那么就找到了弹出元素,如果并不相等,则需要将其他的压入元素压入到栈中,同时比较是不是和当前弹出元素相等,如果遇到一个相等的元素那么便可以结束压入过程,该元素就是弹出元素,如果将所有的元素都压入了栈中还是没有找到,这说明弹出序列并不是压入序列的弹出序列。
作者原创,如需转载及其他问题请邮箱联系:lwqiang_chn@163.com。
个人网站:https://www.myqiang.top。
网友评论