返回

揭秘验证栈序列的奥秘:LeetCode 题 946 深度解析

前端

算法揭秘:验证栈序列

引言

在编程领域,栈是一种至关重要的数据结构,它遵循后进先出的原则。在 LeetCode 题 946 中,我们面临一项看似简单的任务:验证两个序列是否代表了同一栈的合法推入和弹出操作。虽然看似简单,但解开这道谜题却蕴藏着算法设计的巧妙和严谨逻辑。

问题

给定两个序列:pushed 表示推入栈中的元素序列,popped 表示弹出栈的元素序列。我们的目标是验证 popped 序列是否可以由 pushed 序列通过一系列推入和弹出操作得到。

算法核心

算法的核心思想是模拟栈的实际操作。我们逐个比较 pushedpopped 序列中的元素,判断它们是否匹配。如果始终匹配,则表示 popped 序列是由 pushed 序列合法生成的。

具体步骤

  1. 创建一个空栈。
  2. pushed 序列中依次取出元素:
    • 如果该元素与栈顶元素相等,则执行弹出操作。
    • 否则,将该元素推入栈中。
  3. 重复步骤 2,直至 pushed 序列处理完毕。
  4. 如果此时栈为空,则 pushedpopped 序列匹配,返回 true;否则,返回 false

代码示例

def validate_stack_sequences(pushed, popped):
  stack = []
  push_idx = 0

  for pop in popped:
    if stack and stack[-1] == pop:
      stack.pop()
    else:
      while push_idx < len(pushed) and pushed[push_idx] != pop:
        stack.append(pushed[push_idx])
        push_idx += 1
      if push_idx >= len(pushed):
        return False

  return not stack

实例解析

pushed = [1, 2, 3, 4, 5] 和 popped = [4, 5, 3, 2, 1] 为例:

  • 创建空栈。
  • pushed 序列取出元素 1,将其推入栈中。
  • pushed 序列取出元素 2,将其推入栈中。
  • pushed 序列取出元素 3,将其推入栈中。
  • pushed 序列取出元素 4,与栈顶元素 3 相等,执行弹出操作。
  • pushed 序列取出元素 5,与栈顶元素 2 相等,执行弹出操作。
  • 此时栈为空,说明 pushedpopped 序列匹配,返回 true

总结

验证栈序列的算法巧妙地模拟了栈的实际操作,通过逐个比较元素,判断两个序列是否匹配。掌握这一算法不仅可以解决 LeetCode 题 946,更能提升我们对栈数据结构和算法的理解,为解决更多编程问题奠定基础。

常见问题解答

  1. 算法的时间复杂度是多少?

    • 时间复杂度为 O(n),其中 n 是 pushedpopped 序列的长度。
  2. 算法的空间复杂度是多少?

    • 空间复杂度为 O(n),因为算法需要使用一个栈来模拟栈的实际操作。
  3. 算法是否可以处理重复元素?

    • 是的,算法可以处理重复元素。
  4. 算法是否适用于嵌套的栈?

    • 否,算法只能验证单层栈。
  5. 算法在编程中的应用场景有哪些?

    • 算法可以用来验证编译器生成的汇编代码是否遵循正确的栈操作顺序。