一、问题描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
- 0<=pushV.length == popV.length <=1000
- -1000<=pushV[i]<=1000
- 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
二、代码
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pushV int整型一维数组
* @param pushVLen int pushV数组长度
* @param popV int整型一维数组
* @param popVLen int popV数组长度
* @return bool布尔型
*/
struct stack {
int top;
int data[1001];
} stack;
void init(struct stack *sk) {
sk->top = 0;
}
void push(struct stack *sk, int a) {
sk->data[sk->top] = a;
sk->top ++;
}
int pop(struct stack *sk) {
sk->top --;
return sk->data[sk->top];
}
int top(struct stack *sk) {
return sk->data[sk->top - 1];
}
bool isempty(struct stack *sk) {
if (sk->top == 0)
return true;
else
return false;
}
bool instack(struct stack *sk, int a) {
for (int i = 0; i < sk->top; i ++) {
if (sk->data[i] == a)
return true;
}
return false;
}
bool IsPopOrder(int* pushV, int pushVLen, int* popV, int popVLen ) {
struct stack sk;
init(&sk);
int push_p = 0; // 指向pushV中尚未入栈的第一个数
int pop_left = popVLen;
push(&sk, pushV[push_p]);
printf("push %d\n", pushV[sk.top - 1]);
push_p ++;
while (1) {
for (int i = 0; i < popVLen; i ++) {
printf("popV[i] %d\n", popV[i]);
// 该数在栈中,则进行出栈操作
if (instack(&sk, popV[i])) {
printf("in stack\n");
while (1) {
printf("pop %d\n", top(&sk));
pop_left --;
if (pop(&sk) == popV[i]) {
break;
}
}
if((sk.top == 0) && (push_p != pushVLen)){
push(&sk, pushV[push_p]);
push_p ++;
}
}
// 该数不在栈中,则进行入栈操作
else {
printf("not in stack\n");
if(push_p == pushVLen){
return false;
}
while (sk.data[sk.top - 1] != popV[i]) {
push(&sk, pushV[push_p]);
printf("[push %d]\n", pushV[push_p]);
push_p ++;
if ((push_p == pushVLen) && (sk.data[sk.top - 1] != popV[i])) {
return false;
}
}
}
}
return true;
}
}
三、算法思路
- 循环遍历popV数组中的每一个数,对于每一个数a有两种情况:
①不在栈中:那么将pushV数组中的数依次push进栈中,直到push的数和a相等
②在栈中:那么对栈进行pop操作,直到pop的数等于a
- 若pushV中所有数据都已经入过栈并且popV中数据还没遍历完,说明popV中有不存在于pushV的数,返回false
- 若popV中全部数据都遍历完成,返回true
四、遇到的问题
- 数组越界:在循环判断栈顶数据是否等于popV[i]时,会出现此时栈为空的情况,那么此时sk[-1]初始化为0,当popV[i]正好为0时,会判断失误。
解决: 在pop后判断栈是否为空,若为空则push;或者改成while(1),在while里判断并push
- 未及时判断pushV中的数是否已经全部入过栈,导致大量奇怪的数入栈