Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目描述:
给定 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 的一个排列
思路分析:
定义一个栈作为辅助,先判断弹出序列里的值是否要弹出栈,不需要则将推入序列里的值压入栈。
最后判断栈是否为空。
-
定义一个切片作为栈。
-
循环以下处理。
-
栈非空,且栈中最顶端的元素 和 弹出序列的第一个值相同,则出栈并从弹出序列中删除该值。
-
栈中最顶端的元素 和 弹出序列的第一个值不同,并且推入序列非空时,则将推入序列的第一个值压入栈,并从推入序列中删除该值。
-
单次循环中既无出栈处理又无入栈处理时,则跳出循环。
-
-
判断栈的长度是否为 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
}
总结:
-
循环中需要注意,要先判断是否要出栈,然后无出栈处理时再判断是否要入栈。
-
golang 的切片处理非常适用于简单的栈操作。