[LeetCode][golang] 946. 验证栈序列

194 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目描述:

946. 验证栈序列

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

示例 1:

输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4, push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1

示例 2:

输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出:false
解释:1 不能在 2 之前弹出。

提示:

1 <= pushed.length <= 1000
0 <= pushed[i] <= 1000
pushed 的所有元素 互不相同
popped.length == pushed.length
popped 是 pushed 的一个排列

思路分析:

定义一个栈作为辅助,先判断弹出序列里的值是否要弹出栈,不需要则将推入序列里的值压入栈。
最后判断栈是否为空。

  1. 定义一个切片作为栈。

  2. 循环以下处理。

    1. 栈非空,且栈中最顶端的元素 和 弹出序列的第一个值相同,则出栈并从弹出序列中删除该值。

    2. 栈中最顶端的元素 和 弹出序列的第一个值不同,并且推入序列非空时,则将推入序列的第一个值压入栈,并从推入序列中删除该值。

    3. 单次循环中既无出栈处理又无入栈处理时,则跳出循环。

  3. 判断栈的长度是否为 0 。

AC 代码:

golang:

// 946. 验证栈序列
func validateStackSequences(pushed []int, popped []int) bool {
   // 栈
   var stack []int

   for {
      // 入栈出栈标记
      isPushed := false
      isPopped := false

      // 栈非空,且栈中最顶端的元素 和 弹出序列的第一个值相同,则出栈并从弹出序列中删除该值
      if len(stack) > 0 && stack[len(stack)-1] == popped[0] {
         // 弹出栈
         stack = stack[:len(stack)-1]
         // 弹出序列非空时,删除该值
         if len(popped) > 0 {
            popped = popped[1:]
            // 出栈标记设为 true
            isPopped = true
         }
      } else if len(pushed) > 0 {
         // 如果推入序列非空,则将推入序列的第一个值压入栈,并从推入序列中删除该值
         stack = append(stack, pushed[0])
         pushed = pushed[1:]
         // 入栈标记设为 true
         isPushed = true
      }

      // 当次循环同时无出栈和入栈处理时,跳出循环
      if !isPushed && !isPopped {
         break
      }
   }

   // 返回栈长度是否为0
   return len(stack) == 0
}

总结:

  1. 循环中需要注意,要先判断是否要出栈,然后无出栈处理时再判断是否要入栈。

  2. golang 的切片处理非常适用于简单的栈操作。