【每日算法】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中的数是否已经全部入过栈,导致大量奇怪的数入栈
目录
相关文章
|
2月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
72 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
2月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
33 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
29天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
2月前
|
算法
数据结构与算法二:栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式
这篇文章讲解了栈的基本概念及其应用,并详细介绍了中缀表达式转换为后缀表达式的算法和实现步骤。
52 3
|
2月前
|
算法
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
这篇文章介绍了动态规划算法中解决最大上升子序列问题(LIS)的方法,包括问题的描述、动态规划的步骤、状态表示、递推方程、计算最优值以及优化方法,如非动态规划的二分法。
71 0
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
|
3月前
|
算法 数据可视化
基于SSA奇异谱分析算法的时间序列趋势线提取matlab仿真
奇异谱分析(SSA)是一种基于奇异值分解(SVD)和轨迹矩阵的非线性、非参数时间序列分析方法,适用于提取趋势、周期性和噪声成分。本项目使用MATLAB 2022a版本实现从强干扰序列中提取趋势线,并通过可视化展示了原时间序列与提取的趋势分量。代码实现了滑动窗口下的奇异值分解和分组重构,适用于非线性和非平稳时间序列分析。此方法在气候变化、金融市场和生物医学信号处理等领域有广泛应用。
142 19
|
2月前
|
算法 C++
【算法单调栈】 矩形牛棚(C/C++)
【算法单调栈】 矩形牛棚(C/C++)
|
3月前
|
算法 数据可视化 数据安全/隐私保护
基于LK光流提取算法的图像序列晃动程度计算matlab仿真
该算法基于Lucas-Kanade光流方法,用于计算图像序列的晃动程度。通过计算相邻帧间的光流场并定义晃动程度指标(如RMS),可量化图像晃动。此版本适用于Matlab 2022a,提供详细中文注释与操作视频。完整代码无水印。
|
4月前
|
机器学习/深度学习 数据采集 算法
【优秀python算法毕设】基于python时间序列模型分析气温变化趋势的设计与实现
本文介绍了一个基于Python的时间序列模型,用于分析和预测2021-2022年重庆地区的气温变化趋势,通过ARIMA和LSTM模型的应用,揭示了气温的季节性和趋势性变化,并提供了对未来气温变化的预测,有助于气象预报和相关决策制定。
【优秀python算法毕设】基于python时间序列模型分析气温变化趋势的设计与实现
|
5月前
|
自然语言处理 算法 搜索推荐
字符串相似度算法完全指南:编辑、令牌与序列三类算法的全面解析与深入分析
在自然语言处理领域,人们经常需要比较字符串,这些字符串可能是单词、句子、段落甚至是整个文档。如何快速判断两个单词或句子是否相似,或者相似度是好还是差。这类似于我们使用手机打错一个词,但手机会建议正确的词来修正它,那么这种如何判断字符串相似度呢?本文将详细介绍这个问题。
283 1