1. 题目
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列{1,2,3,4,5}是某栈的压栈序列,序列{4,5,3,2,1}是该压栈序列对应的一个弹出序列,但{4,3,5,1,2}就不可能是该压栈序列的弹出序列。
2. 解题思路
多举举例子,找到规律,也就是代码的逻辑。
建立一个辅助栈,把输入的第一个序列中的数字依次压入该辅助栈,并按照第二个序列的顺序依次从该栈中弹出数字
分析弹出序列,
如果辅助栈的栈顶数字等于弹出序列中的当前元素,那么直接弹出,弹出序列指针右移
如果弹出序列中的当前数字不在栈顶,则把压栈序列中还没有入栈的数字压入辅助栈,直到把下一个需要弹出的数字压入栈顶位置
如果所有数字都压入栈后仍然没有找到下一个弹出的数字,那么该序列不可能是一个弹出序列。
3. 代码实现
# 定义栈类
class Stack(object):
# 初始化栈为空列表
def __init__(self):
self.values = []
# 向栈顶压入一个新数据项
def push(self, value):
self.values.append(value)
# 返回栈顶元素,并删除
def pop(self):
return self.values.pop()
# 判断栈是否为空
def is_empty(self):
return self.size() == 0
# 返回栈的大小
def size(self):
return len(self.values)
# 返回栈顶数据项,但不删除。
def peak(self):
return self.values[self.size()-1]
def is_pop_order(push_list, pop_list):
# 是否是压栈序列的弹出序列,默认不是
possible = False
# 建立一个辅助栈
stack_data = Stack()
i = 0 # 指向压入序列的指针
j = 0 # 指向弹出序列的指针
if push_list and pop_list and len(push_list) == len(pop_list):
# 外层循环控制的是,弹出序列的指针移动
while j < len(pop_list):
# 内层循环控制的是,栈顶元素是谁,是否需要将元素压入栈中
# 当栈为空,或者辅助栈的栈顶数字不等于弹出序列中的当前元素时,向辅助栈中压入数字
while stack_data.is_empty() or stack_data.peak() != pop_list[j]:
# 在辅助栈中压入一个数字,然后判断这个数字是否是弹出序列中的第一个数字,
# 是,表明此数字作为栈顶弹出过?否,则继续压入数字?
if i < len(push_list):
print("当前压入序列元素{}".format(push_list[i]))
stack_data.push(push_list[i])
i += 1
else:
# return False
print("已经遍历完压栈序列")
break
# 什么原因退出的内层while循环
if stack_data.peak() != pop_list[j]: # 不是因为stack_data.peak() == pop_list[j]而退出的内层循环
print("辅助栈的栈顶元素{}, 弹出序列当前元素{}".format(stack_data.peak(), pop_list[j]))
break
# 是因为stack_data.peak() == pop_list[j]而退出的内层循环
res_pop = stack_data.pop()
print("栈顶元素{}等于弹出序列当前元素,弹出该元素, 同时弹出指针右移一位".format(res_pop))
j += 1
# 最后,只有当辅助栈中没有元素了,且指针已经指向了弹出序列的末尾时,才能确定这个弹出序列是此压入序列的一个弹出序列。
# 防止辅助栈的长度大于或小于弹出序列的长度
if stack_data.is_empty() and j == len(pop_list):
possible = True
return possible
if __name__ == '__main__':
push_list = [1, 2, 3, 4, 5]
pop_list = [4, 5, 3, 1, 2]
result = is_pop_order(push_list, pop_list)
print(result)
4. 总结
在应对栈相关的问题时,首先是举例子,然后画图,找出思路,最后才写代码。而且,这类问题常常需要使用辅助栈。
5. 参考文献
[1] 剑指offer丛书