返回

用 Stack 解密推入、弹出序列的奥秘

前端

栈的魅力:简单却强大的数据结构

栈是一种简单却强大的数据结构,它有着诸多优点:

  • 遵循后进先出的原则(LIFO),使元素的添加和移除操作非常高效。
  • 易于理解和实现,代码简洁且易于维护。
  • 广泛应用于各种场景,如函数调用、括号匹配、表达式求值等。

LeetCode 946:验证栈序列

在 LeetCode 上,「验证栈序列」的题目如下:

给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false。

简单来说,我们需要判断是否可以使用给定的推入序列和弹出序列来模拟一个栈的操作,使得推入和弹出元素的顺序与给定序列一致。

算法思路:模拟栈的操作

为了解决这个问题,我们可以使用栈的数据结构来模拟实际的栈操作。算法思路如下:

  1. 初始化一个空栈。
  2. 遍历推入序列,依次将元素推入栈中。
  3. 遍历弹出序列,依次将栈顶元素弹出。
  4. 如果在弹出元素时,栈为空,说明给定的序列不合法,返回 false。
  5. 如果弹出序列中最后一个元素不是栈顶元素,说明给定的序列不合法,返回 false。
  6. 如果弹出序列中所有元素都能够被正确弹出,说明给定的序列是合法的,返回 true。

代码实现

def validate_stack_sequences(pushed, popped):
    """
    验证推入和弹出序列是否对应于同一个栈

    参数:
        pushed (list): 推入序列
        popped (list): 弹出序列

    返回:
        bool: 如果序列对应于同一个栈,返回 True;否则,返回 False
    """

    # 初始化一个空栈
    stack = []

    # 遍历推入序列,依次将元素推入栈中
    for x in pushed:
        stack.append(x)

    # 遍历弹出序列,依次将栈顶元素弹出
    for x in popped:
        # 如果栈为空,说明序列不合法
        if not stack:
            return False

        # 如果栈顶元素不等于当前要弹出的元素,说明序列不合法
        if stack[-1] != x:
            return False

        # 弹出栈顶元素
        stack.pop()

    # 如果弹出序列中所有元素都能够被正确弹出,说明序列是合法的
    return True


# 测试用例
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, 6]),  # False
]

for pushed, popped in test_cases:
    print(f"推入序列:{pushed}")
    print(f"弹出序列:{popped}")
    result = validate_stack_sequences(pushed, popped)
    print(f"验证结果:{result}")
    print()

结语

通过这道 LeetCode 难题,我们深入剖析了栈的数据结构及其应用。希望通过本文,你能够对栈有更深入的理解,并能够将其应用到实际的编程场景中。