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

简介: 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

  1. 若pushV中所有数据都已经入过栈并且popV中数据还没遍历完,说明popV中有不存在于pushV的数,返回false
  2. 若popV中全部数据都遍历完成,返回true

四、遇到的问题

  1. 数组越界:在循环判断栈顶数据是否等于popV[i]时,会出现此时栈为空的情况,那么此时sk[-1]初始化为0,当popV[i]正好为0时,会判断失误。

解决: 在pop后判断栈是否为空,若为空则push;或者改成while(1),在while里判断并push

  1. 未及时判断pushV中的数是否已经全部入过栈,导致大量奇怪的数入栈
目录
相关文章
|
16天前
|
存储 算法 调度
数据结构与算法-栈篇
数据结构与算法-栈篇
16 3
|
2天前
|
算法 C语言
【数据结构与算法 经典例题】使用栈实现队列(图文详解)
【数据结构与算法 经典例题】使用栈实现队列(图文详解)
|
2天前
|
算法 C语言
【数据结构与算法 经典例题】使用队列实现栈(图文详解)
【数据结构与算法 经典例题】使用队列实现栈(图文详解)
|
3天前
|
算法
【C/数据结构和算法】:栈和队列
【C/数据结构和算法】:栈和队列
13 1
|
22天前
|
算法 C语言
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
18 2
|
2天前
|
存储 算法 编译器
【数据结构与算法】使用数组实现栈:原理、步骤与应用
【数据结构与算法】使用数组实现栈:原理、步骤与应用
|
2天前
|
算法
【数据结构和算法】---栈和队列的互相实现
【数据结构和算法】---栈和队列的互相实现
5 0
|
2天前
|
缓存 算法
【数据结构和算法】--- 栈
【数据结构和算法】--- 栈
4 0
|
7天前
|
算法 Java 编译器
Java数据结构与算法:线性数据结构之栈
Java数据结构与算法:线性数据结构之栈
|
1月前
|
算法 C++
c++算法学习笔记 (15) 单调栈与单调队列
c++算法学习笔记 (15) 单调栈与单调队列