题目描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。
示例 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 之前弹出。
提示:
0 <= pushed.length == popped.length <= 1000
0 <= pushed[i], popped[i] < 1000
pushed 是 popped 的排列。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
模拟入栈和出栈
先创建一个栈,把入栈序列压入栈中,不过不是一次性全部压入,因为可能会先弹出一些元素,再压入元素
压入一个元素之后,就判断当前栈顶元素与popped序列的当前元素是否相等,不相等,则继续压入元素,如果相等,则弹出栈顶元素,同时,应该有一个变量记录当前判断到popped序列的哪一个元素了
继续循环判断当期栈顶元素与popped序列的当前元素是否相等,不满足循环条件就继续压入元素,直到pushed序列都已经压入到栈中
最后判断当前栈是否为空,如果popped序列是pushed序列的弹出序列,则当前栈应该为空。
代码
class Solution {
public boolean validateStackSequences(int[] pushed, int[] popped) {
Stack<Integer> stack=new Stack();
int count=0;
for(int i=0;i<pushed.length;i++)
{
stack.push(pushed[i]);//模拟入栈
while(!stack.empty()&&stack.peek().intValue()==popped[count])//模拟出栈,当当前栈顶元素和popped[count]相等,就出栈
{//这里用while循环的原因是可能出栈一个元素之后, count++; ,当前栈的栈顶元素依然等于popped[count]
//如果只用if,则for循环结束,程序也就结束了
int k=stack.pop();
//System.out.println(k);
count++;
}
}
return stack.empty();//栈为空,说明入栈序列按照出栈序列都弹出了,如果栈不为空,说明给定的popped序列不是入栈序列的弹出序列
}
}
class Solution {
public boolean validateStackSequences(int[] pushed, int[] popped) {
Stack<Integer> stack = new Stack<>();
int i = 0;
for(int num : pushed) {
stack.push(num); // num 入栈
while(!stack.isEmpty() && stack.peek() == popped[i]) { // 循环判断与出栈
stack.pop();
i++;
}
}
return stack.isEmpty();
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof/solution/mian-shi-ti-31-zhan-de-ya-ru-dan-chu-xu-lie-mo-n-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
模拟
class Solution {
/* // 模拟 */
public boolean validateStackSequences(int[] pushed, int[] popped) {
int n = pushed.length;
// 设置一个栈模拟出栈入栈行为
Stack<Integer> s = new Stack<>();
// 逐个检查能否得到popped出栈序列
for (int i = 0, j = 0; j < n;) {
// 若栈顶元素不是当前popped序列所处理的那个或栈空,那就从pushed序列取元素入栈
while (i < n && (s.empty() || s.peek() != popped[j]))
s.push(pushed[i++]);
// 如果出栈序列用完了都得不到出栈序列元素,说明pushed的入栈顺序不可能得到popped的出栈顺序
if (i == n && s.peek() != popped[j])
return false;
while (!s.empty() && s.peek() == popped[j]) {
s.pop();
++j;
}
}
return true;
}
}
作者:meteordream
链接:https://leetcode-cn.com/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof/solution/jian-zhi-31zhan-de-ya-ru-dan-chu-xu-lie-heedx/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
空间优化+模拟
下面这个代码可能得结合上面的模拟代码才能看懂
class Solution {
/* // 模拟 + 空间压缩 */
// 注意到我们设置用于模拟的栈大小不会超出pushed的大小,且pushed和popped的元素都只需遍历一次就行,那么我们可以在pushed上原地进行模拟,其余思路不变
public boolean validateStackSequences(int[] pushed, int[] popped) {
int n = pushed.length;
// pushed 已经遍历过的位置设置一个模拟栈的栈顶指针
int s = 0;
// 逐个检查能否得到popped出栈序列
for (int i = 0, j = 0; j < n;) {
// 若栈顶元素不是当前popped序列所处理的那个或栈空,那就从pushed序列取元素入栈
while (i < n && (s == 0 || pushed[s - 1] != popped[j]))
//s-1是因为压入一个元素之后,s加了1表示当前栈中的元素个数,取栈顶肯定是s-1呀,s还没放元素呢
pushed[s++] = pushed[i++];
// 如果出栈序列用完了都得不到出栈序列元素,说明pushed的入栈顺序不可能得到popped的出栈顺序
if (i == n && pushed[s - 1] != popped[j])
return false;
while (s > 0 && pushed[s - 1] == popped[j]) {
--s;
++j;
}
}
return true;
}
}
作者:meteordream
链接:https://leetcode-cn.com/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof/solution/jian-zhi-31zhan-de-ya-ru-dan-chu-xu-lie-heedx/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。