题目描述:
输入两个整数序列,其中一个序列表示栈的push顺序,判断另一个序列有没有可能是对应的pop序列
思路:
假如输入的 push 序列为1、2、3、4、5,那么3、2、5、4、1就有可能是一个 pop 序列,但5、3、4、1、2就不可能是一个 pop 序列。
使用一个栈来模拟入栈顺序,步骤
如下:
(1) 把push序列依次入栈,直到栈顶元素等于pop序列的第一个元素,然后栈顶元素出栈,pop 序列移动到第二个元素;
(2) 如果栈顶元素继续等于pop序列现在的元素,则继续出栈并将pop序列的元素后移,否则对push序列继续入栈;
(3) 如果push序列全部入栈,但是pop序列未全部遍历,而且栈顶元素不等于当前pop元素,那么这个序列不是一个可能的pop序列。
下图给出一个合理的pop序列的判断过程:
在上图中,(1)~(3)三步,由于栈顶元素不等于pop序列的第一个元素3,所以,1,2,3依次入栈;当3入栈后,栈顶元素为3,等于pop序列的第一个元素,所以第(4)步执行3出栈,接下来指向pop序列的第二个元素2,且此时栈顶元素也为2,所以第(5)步执行2出栈,接着栈顶元素4不等于当前pop序列元素的5,所以接下来(6)和(7)两步分别执行4,5入栈,接着由于栈顶元素5等于pop序列的当前值,所以第(8)步执行5出栈,接下来(9)和(10)两步栈顶元素等于当前pop序列的元素,所以都执行出栈操作。最后由于栈为空且pop序列完成了遍历,所以{3,2,5,4,1}是一个合理的出栈序列。
算法性能分析:
本算法需要把push序列入栈再出栈操作,操作次数为2n,所以时间复杂度为O(n);
此外这种方法需要额外的栈空间,所以空间复杂度为O(n);
代码实现:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2020/1/21 16:17
# @Author : buu
# @Software: PyCharm
# @Blog :https://blog.csdn.net/weixin_44321080
class Mystack: # 新建一个栈类
def __init__(self): # 模拟栈
self.items = [] # 用列表实现
def isEmpty(self): # 栈是否为空
return len(self.items) == 0
def size(self): # 栈的大小
return len(self.items)
def peek(self): # 取栈顶元素
if not self.isEmpty():
return self.items[len(self.items) - 1]
else:
return None
def pop(self): # 弹栈
if len(self.items) > 0: # 先判断栈是否为空
return self.items.pop()
else:
print('stack is empty!')
return None
def push(self, item): # 入栈
self.items.append(item)
def isPopSerial(push, pop):
"""
判断pop是否为push的一个对应的出栈序列
:param push: 入栈序列
:param pop: 出栈序列
:return: True or False
"""
if push == None or pop == None:
return False
pushLen = len(push)
popLen = len(pop)
if pushLen != popLen:
return False
pushIndex = 0
popIndex = 0
stack = Mystack()
while pushIndex < pushLen:
stack.push(push[pushIndex])
pushIndex += 1
while not stack.isEmpty() and stack.peek() == pop[popIndex]:
stack.pop()
popIndex += 1
return stack.isEmpty() and popIndex == popLen
if __name__ == '__main__':
push = [1, 2, 3, 4, 5]
pop = [3, 2, 5, 4, 1]
if isPopSerial(push, pop):
print('yes!')
else:
print('no!')
结果:
end