echo

任生命穿梭 时间的角落

0%

验证栈序列

946. 验证栈序列

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

示例 1:

1
2
3
4
5
输入: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:

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

提示:

  1. 0 <= pushed.length == popped.length <= 1000
  2. 0 <= pushed[i], popped[i] < 1000
  3. pushedpopped 的排列。

方法一:模拟

我们模拟做题过程中判断是否为出栈序列的方法,将入栈序列中的元素依次入栈,在入栈的过程中,如果栈顶元素与出栈序列的第一个元素相同则将栈顶元素弹出,直到最后栈中元素为空。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Solution {
public static boolean validateStackSequences(int[] pushed, int[] popped) {
int m = pushed.length, n = popped.length;
//入栈序列长度与出栈序列长度不相同
if(m != n){
return false;
}

LinkedList<Integer> stack = new LinkedList<>();
int i = 0, j = 0;

//是否出栈完成
while(j != n){
//入栈元素与出栈元素不相同,添加元素
while(i < m && pushed[i] != popped[j]){
stack.addLast(pushed[i++]);
}
//入栈元素与出栈元素相同,先将其入栈,然后再出栈
if(i < m && pushed[i] == popped[j]){
stack.addLast(pushed[i++]);
}
//栈顶元素与出栈元素相同则出栈
while(stack.size() > 0){
if(stack.peekLast() == popped[j]){
stack.removeLast();
j++;
}else {
//无元素入栈,栈顶元素与出栈元素不相同
if(i == m)
return false;
else//还有元素入栈,跳出循环,继续进行进栈操作
break;
}
}
}
return true;
}
}

时间复杂度O(n),空间复杂度O(1)。

方法二:贪心

将 pushed 队列中每个数都 push 到栈中,同时检查这个数是不是 popped 序列中下一个要 pop 的值,如果是,就要把它 pop 出来。

最后,检查是否所有的值都 pop 出来了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public static boolean validateStackSequences(int[] pushed, int[] popped) {
int m = pushed.length;
LinkedList<Integer> stack = new LinkedList<>();
int j = 0;

for(int x : pushed){
stack.addLast(x);
while(stack.size() != 0 && stack.peekLast() == popped[j]){
stack.removeLast();
++j;
}
}
return j == m;
}
}

时间复杂度O(n),空间复杂度O(1)。