21 栈的压入、弹出序列
题目描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。
示例:
输入: pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出: True
输入: pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出: False解题思路
核心思想:模拟栈的压入和弹出过程。
关键步骤:
- 创建一个模拟栈
- 按压入顺序依次压入元素
- 每压入一个元素,检查栈顶是否等于弹出序列的下一个元素
- 如果相等则弹出,继续检查
- 最后检查模拟栈是否为空
时间复杂度:O(n) 空间复杂度:O(n)
Python 实现
python
def is_valid_stack_sequence(pushed, popped):
"""
判断popped是否是pushed的合法弹出序列
Args:
pushed: 压入序列
popped: 弹出序列
Returns:
bool: 是否合法
"""
if len(pushed) != len(popped):
return False
stack = []
pop_index = 0
for num in pushed:
stack.append(num)
# 检查栈顶是否等于下一个要弹出的元素
while stack and stack[-1] == popped[pop_index]:
stack.pop()
pop_index += 1
return not stack
# 测试代码
if __name__ == "__main__":
test_cases = [
([1, 2, 3, 4, 5], [4, 5, 3, 2, 1]), # True
([1, 2, 3, 4, 5], [4, 3, 5, 1, 2]), # False
([1, 2, 3, 4, 5], [1, 2, 3, 4, 5]), # True
]
for pushed, popped in test_cases:
result = is_valid_stack_sequence(pushed, popped)
print(f"pushed={pushed}, popped={popped} → {result}")
# 输出:
# pushed=[1, 2, 3, 4, 5], popped=[4, 5, 3, 2, 1] → True
# pushed=[1, 2, 3, 4, 5], popped=[4, 3, 5, 1, 2] → False
# pushed=[1, 2, 3, 4, 5], popped=[1, 2, 3, 4, 5] → True图解
示例: pushed=[1,2,3,4,5], popped=[4,5,3,2,1]
压入1, 栈=[1], 栈顶1≠4
压入2, 栈=[1,2], 栈顶2≠4
压入3, 栈=[1,2,3], 栈顶3≠4
压入4, 栈=[1,2,3,4], 栈顶4=4, 弹出→栈=[1,2,3], pop_index=1
继续检查, 栈顶3≠5
压入5, 栈=[1,2,3,5], 栈顶5=5, 弹出→栈=[1,2,3], pop_index=2
继续检查, 栈顶3=3, 弹出→栈=[1,2], pop_index=3
继续检查, 栈顶2=2, 弹出→栈=[1], pop_index=4
继续检查, 栈顶1=1, 弹出→stack=[], pop_index=5
栈为空,返回True