题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
解法一:借用辅助栈
public static boolean IsPopOrder (int[] pushV, int[] popV) {
// write code here
Stack<Integer> stack = new Stack<>(); //创建一个辅助栈
int i = 0; //i用来遍历入栈的下标
//j用来遍历出栈的下标
for(int j = 0; j< pushV.length; j++){
//入栈的条件,i的下标比长度小,且栈为空或者栈顶元素和待匹配元素不同
//主要为了避免这种特殊情况 [1] [2]
while( i < pushV.length && (stack.isEmpty()||stack.peek()!=popV[j]) ){
stack.push(pushV[i]); //插入元素
i++; //移动遍历入栈的下标
}
//当执行到该if语句的时候只有可能两种情况 1. pushV被遍历完了,或者是栈顶元素和目前的出栈元素相同
//如果pushV被遍历完了但是栈顶元素和目前的待出栈元素不同直接返回false;
if(stack.peek() == popV[j]){
stack.pop();
}else
return false;
}
return true;
解法二:原地栈
将push数组模拟成栈,来进行入栈和出栈操作,但是整个过程会对原始数组进行修改。
public static boolean IsPopOrder (int[] pushV, int[] popV) {
// 将pushV数组视为一个栈,利用数组前边使用过的部分
int n = 0; // 表示目前栈空间的大小
int j = 0; // 出栈序列的下标
for (int number : pushV) { //遍历待插入数组
//将该元素插入数组,需要注意的是在后续的操作中可能会出现元素覆盖,主要是因为有的元素逻辑上已经出栈,这部分存储就不需要了
pushV[n] = number;
//当栈顶元素与序列元素比较,相同进行出栈操作,此时出栈元素所处的空间就可以被覆盖
while(n >= 0 && pushV[n] ==popV[j]){
j++;
n--;
}
n++; //当pushV[0] = 某一个值时会导致n=-1,所以n++,插入元素后也需要移动到下一位,移除某个元素后也需要利用该位置存储其他元素
}
return n==0;
}
新人学习代码,有问题欢迎随时评论交流,看到就会回复,谢谢大家。