输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
1. 0<=pushV.length == popV.length <=1000
2. -1000<=pushV[i]<=1000
3. pushV 的所有数字均不相同
[1,2,3,4,5],[4,5,3,2,1]
true
可以通过push(1)=>push(2)=>push(3)=>push(4)=>pop()=>push(5)=>pop()=>pop()=>pop()=>pop() 这样的顺序得到[4,5,3,2,1]这个序列,返回true
[1,2,3,4,5],[4,3,5,1,2]
false
由于是[1,2,3,4,5]的压入顺序,[4,3,5,1,2]的弹出顺序,要求4,3,5必须在1,2前压入,且1,2不能弹出,但是这样压入的顺序,1又不能在2之前弹出,所以无法形成的,返回false
【思路】借用一个辅助的栈,遍历压栈顺序,先讲第一个放入栈中,这里是1,然后判断栈顶元素是不是出栈顺序的第一个元素,这里是4,很显然1≠4,所以我们继续压栈,直到相等以后开始出栈,出栈一个元素,则将出栈顺序向后移动一位,直到不相等,这样循环等压栈顺序遍历完成,如果辅助栈还不为空,说明弹出序列不是该栈的弹出顺序。
举例:
入栈1,2,3,4,5
出栈4,5,3,2,1
首先1入辅助栈,此时栈顶1≠4,继续入栈2
此时栈顶2≠4,继续入栈3
此时栈顶3≠4,继续入栈4
此时栈顶4=4,出栈4,弹出序列向后一位,此时为5,,辅助栈里面是1,2,3
此时栈顶3≠5,继续入栈5
此时栈顶5=5,出栈5,弹出序列向后一位,此时为3,,辅助栈里面是1,2,3
….
import java.util.ArrayList; import java.util.Stack; public class Solution { public boolean IsPopOrder(int [] pushA,int [] popA) { if(pushA.length == 0 || popA.length == 0) return false; Stack<Integer> s = new Stack<Integer>(); //用于标识弹出序列的位置 int popIndex = 0; for(int i = 0; i< pushA.length;i++){ s.push(pushA[i]); //如果栈不为空,且栈顶元素等于弹出序列 while(!s.empty() &&s.peek() == popA[popIndex]){ //出栈 s.pop(); //弹出序列向后一位 popIndex++; } } return s.empty(); } }
import java.util.ArrayList; public class Solution { public boolean IsPopOrder(int [] pushA,int [] popA) { if(pushA.length==0||popA.length==0) return false; ArrayList<Integer> list = new ArrayList<Integer>(); int j = 0; for(int i = 0;i<pushA.length;i++){ if(pushA[i]!=popA[j]) list.add(pushA[i]); else j++; } for(int i = list.size()-1;i>=0;i--){ if(list.get(i)!=popA[j]) return false; j++; } return true; } }
class Solution { public: bool IsPopOrder(vector<int> pushV, vector<int> popV) { auto i = pushV.begin(); while (s.size()<pushV.size()&&popV.size()>0) { if (i != pushV.end()) { s.push(*i); i++; } if (s.top()==*popV.begin()) { s.pop(); popV.erase(popV.begin(), popV.begin()+1); } else { if (i==pushV.end()) { return false; } } } return popV.size() > 0 ? false : true; } private: stack<int> s; };
//栈的压入、弹出序列 bool IsPopOrder(vector<int> pushV,vector<int> popV) { bool flag=false; if(pushV.size() >0) { stack<int> s; unsigned int i=0; //指向pushV unsigned int j=0; //指向popV while(j<popV.size()) { while((i<pushV.size()) && (s.empty() || s.top()!= popV[j])) s.push(pushV[i++]); if(s.top() != popV[j]) break; else { s.pop(); ++j; } } if(s.empty() && j==popV.size()) flag=true; } return flag; }
# -*- coding:utf-8 -*- class Solution: def __init__(self): self.stack = [] def IsPopOrder(self, pushV, popV): # write code here self.stack.append(pushV.pop(0)) while self.stack: if self.stack[-1] == popV[0]: self.stack.pop(-1) popV.pop(0) elif pushV: self.stack.append(pushV.pop(0)) else: return False return Truea little complex but easy to understand, simulate the situation when a stack works
class Solution { public: bool IsPopOrder(vector<int> pushV,vector<int> popV) { stack<int> sk; int idx = 0;//用于标识弹出序列的位置 for(int i=0;i<pushV.size();i++){ sk.push(pushV[i]);//先入栈 //再循环判断当前栈顶元素是否是popV的出栈元素 while(idx<popV.size()&&!sk.empty()&&popV[idx]==sk.top()){ sk.pop();//出栈 idx++;//弹出序列向后一位 } } return sk.empty();//为空则为true } };
function IsPopOrder(pushV, popV) { // write code here let stack = []; let j = 0; let length = pushV.length; for(let i = 0;i < length;i++) { stack.push(pushV[i]); // 如果没有j<length显示条件,stack为空时,stack[-1]是undefined // popV[j]也是undefined,因为此时j已经超过了数组的长度,就是死循环了 while(j < length && popV[j] === stack[stack.length - 1]) { stack.pop(); j++; } } return stack.length === 0; } module.exports = { IsPopOrder : IsPopOrder };
import java.util.*; public class Solution { public boolean IsPopOrder(int [] pushA,int [] popA) { Stack<Integer> stack = new Stack<>(); int p2Index = 0; for (int i = 0; i < pushA.length; i++) { stack.add(pushA[i]); while (!stack.isEmpty() && stack.peek() == popA[p2Index]){ p2Index++; stack.pop(); } } return p2Index == popA.length; } }
# -*- coding:utf-8 -*- class Solution: def IsPopOrder(self, pushV, popV): # write code here stack = [] index = 0 for inV in pushV: stack.append(inV) while stack and stack[-1] == popV[index]: index +=1 stack.pop() return len(stack)==0
# -*- coding:utf-8 -*- # 基本思想:按入栈顺序,将pushV的元素依次入stack栈,如果栈顶元素等于popV的第一个元素, # 此时要将stack的栈顶元素出栈,并丢掉popV的第一个元素,此时,如果栈顶元素仍然等于popV的 # 第一个元素,则继续出战,直到值不相等时,继续将pushV的元素入栈,反复操作直到pushV为空。 # 此时只需要判断stack和popV是否相反,如果是,返回true, 否则返回false。 def IsPopOrder(self, pushV, popV): # write code here if not pushV&nbs***bsp;not popV: return False stack = [] # 定义一个栈 equal = False # 标志位,如果为true,则继续出栈操作,不进行入栈操作 while pushV: if not equal or not stack: stack.append(pushV.pop(0)) if stack[-1] != popV[0]: equal = False continue equal = True stack.pop() popV.pop(0) if len(stack) != len(popV): return False while stack: if stack.pop() != popV.pop(0): return False return True
# -*- coding:utf-8 -*- class Solution: def IsPopOrder(self, pushV, popV): result = [] index = 0 for i in pushV: result.append(i) while result != [] and result[-1] == popV[index]: result.pop() index += 1 if result == []: return True return False
import java.util.ArrayList; import java.util.Stack; public class Solution { public boolean IsPopOrder(int [] pushA,int [] popA) { Stack<Integer> stack = new Stack<>(); int j=0; for(int i=0;i<pushA.length;i++){ if(pushA[i]==popA[j]){ j++; while(!stack.isEmpty()&&stack.peek()==popA[j]){ stack.pop(); j++; } }else{ stack.push(pushA[i]); } } return stack.isEmpty(); } }
//没有新开辟空间的做法 class Solution { public: bool IsPopOrder(vector<int> pushV,vector<int> popV) { //如果序号a出栈 那么后面的序号里面(如果有小于a的序号)一定是按照栈反序 if(pushV.size()!=popV.size()) { return false; } map<int,int>hash; for(int i=0;i<pushV.size();i++) { hash[pushV[i]]=i;//值是key 索引是value } for(int i=0;i<popV.size();i++) { //索引是hash[popV[i]] if(hash.count(popV[i])==0) { return false; } int tmp=hash[popV[i]]; for(int j=i;j<popV.size();j++) { if(hash[popV[i]]>hash[popV[j]]) { if(hash[popV[j]]>tmp) { return false; } else if(tmp>hash[popV[j]]) { tmp=hash[popV[j]]; } } } } return true; } };