【每日算法】AB2 栈的压入、弹出序列

问题描述

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列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

代码

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 *
 * @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;
    }
}

算法思路

  1. 循环遍历popV数组中的每一个数,对于每一个数a有两种情况:
    ①不在栈中:那么将pushV数组中的数依次push进栈中,直到push的数和a相等
    ②在栈中:那么对栈进行pop操作,直到pop的数等于a
  2. 若pushV中所有数据都已经入过栈并且popV中数据还没遍历完,说明popV中有不存在于pushV的数,返回false
  3. 若popV中全部数据都遍历完成,返回true

遇到的问题

  1. 数组越界:在循环判断栈顶数据是否等于popV[i]时,会出现此时栈为空的情况,那么此时sk[-1]初始化为0,当popV[i]正好为0时,会判断失误。
    解决: 在pop后判断栈是否为空,若为空则push;或者改成while(1),在while里判断并push
  2. 未及时判断pushV中的数是否已经全部入过栈,导致大量奇怪的数入栈
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值