数据结构与算法--举例分析法- 栈的压入弹出序列

举例分析

  • 与上两篇问中画图方法一样,我们可以用举例模拟的方法思考分析复杂问题。当一眼不能看出问题的规律的时候,我们可以用几个具体的例子来模拟一下问题的过程。这样就和我们在程序出现问题时候的debug一样,走一下整个流程,可以直观的看到整个过程。
  • 具体的例子还能帮助我们确保代码的质量,在编码完成后,可以将例子当做测试用例来模拟运行,看每一步操作后的结果和我们预期的是不是一样的。

包含min方法的栈

  • 题目:定义栈的数据结构,请在改类型中实现一个能够得到栈的最小元素min函数。在改栈中,调用min,push,pop的时间复杂度O(1)
  • 此处与普通栈不同点在于需要知道每次栈变动时候最小值。并且难点在于O(1)的时间复杂度,我们第一反应是标记最小值,这样可以在O(1)时间得到最小元素。但是最小值出栈后,次小的值就变成最小值,此时是无法获取这个值
  • 另外一个思路,每次入栈对栈中元素进行排序,这样能拿到最小值在栈首,会在尾。但是这样就违背了栈的后进先出的原则就不是栈了。
  • 分析到此处发现一个栈A并不能解决问题,我们用一个辅助的栈空间B,每次添加一个元素到A时候,将添加元素与最小元素比较(临时变量保存最小元素),将最小元素添加到B,即使最小元素没有变化仍然重复添加到B占位用。我们用如下案例分析:
步骤操作数据栈A辅助栈B最小值
1压入3333
2压入63,63,33
3压入43,6,43,3,33
4压入453,6,4,453,3,3,33
5压入03,6,4,45,03,3,3,3,00
6压入23,6,4,45,0,23,3,3,3,0,00
  • 如上表格,我们将最小元素每次都添加到辅助栈B中,就能保证辅助栈的栈顶是最小元素。

  • 当最小元素从数据栈弹窗,我们同时操作辅助栈弹窗,这样保证辅助栈下一个值是最小值。

  • 每一步操作数据栈,辅助站都同步,可以保证辅助栈顶永远都是数据栈中所有数据的最小值

  • 实现方法是在之前文章数据结构与算法–简单栈实现及其应用基础上完成。实现如下:

/*** 包含min方法的栈实现* @author liaojiamin* @Date:Created in 16:02 2021/4/2*/
public class MyStackWithMin {private static MyStack dataStack = new MyStack();private static MyStack minStack = new MyStack();public static void push(int num){if(dataStack.size() == 0 && minStack.size() == 0){dataStack.push(num);minStack.push(num);}else {dataStack.push(num);if((int)minStack.getTop() > num){minStack.push(num);}else {minStack.push(minStack.getTop());}}}public static int pop(){if(dataStack.size() == 0 || minStack.size() == 0){return Integer.MAX_VALUE;}minStack.pop();return (int)dataStack.pop();}public static int min(){if(minStack.size() == 0){return Integer.MAX_VALUE;}return (int)minStack.pop();}public static void main(String[] args) {Random random = new Random();for (int i = 0; i < 100; i++) {int temp = random.nextInt(100);System.out.println(temp);push(temp);}System.out.println(min());}
}

栈的压入,弹出序列

  • 题目:输入两个整数序列,第一个序列表示栈的压入顺序,判断第二个序列是否可能是栈的弹出顺序,假设入站的所有数字均不相等,例如:1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是可能的一个出栈,但是4,3,5,1,2就不可能是出栈的方式
  • 我们依然用案例的方法分析,如下表格分析题中两种情况。
步骤操作弹出数字
1压入11
2压入21,2
3压入31,2,3
4压入41,2,3,4
5弹出1,2,34
6压入51,2,3,5
7弹出1,2,35
8弹出1,23
9弹出12
10弹出1
  • 如上表格中每一个步骤操作,我们在第五步骤时候,弹出4,压入5,之后持续弹出,就能得到对应的弹出序列。
  • 我们用同样的方式来递推第二个序列
步骤操作弹出数字
1压入11
2压入21,2
3压入31,2,3
4压入41,2,3,4
5弹出1,2,34
6弹出1,23
7压入51,2,5
8弹出1,25
9下一个弹出的是1,但是1 不在栈顶,压栈序列已经都入栈,操作无法继续
  • 如上两表格分析,入栈,出栈过程,我们可以判断一个序列是不是栈的弹出序列有如下规律:
    • 如果下一个弹出的数字正好是栈顶数字,那么直接弹出
    • 如果下一个弹出的数字不在栈顶,我们吧压栈序列中还没有入栈的数字压入辅助栈
    • 持续压入直到下一个需要弹出的数字压入栈顶位置
    • 如果所有数字都压入了栈但是还没找到下一个弹出的数字,那么该序列不存在一个弹出序列。
    • 综上有如下实现:
/*** 存在栈A的入栈系列S,判断给出的序列B是否可能是A 的出序列,例如1,2,3,4,5 入栈,4,5,3,2,1 出栈* @author liaojiamin* @Date:Created in 16:54 2021/4/2*/
public class ValidateIsPopOrder {public static boolean validateIsPopOrder(int[] orderPush, int[] orderPop){if(orderPush == null || orderPop == null){return false;}if(orderPush.length != orderPop.length){return false;}MyStack myStack = new MyStack();int length = orderPop.length;int pushPosition = 0;int popPosition = 0;while (pushPosition < length || popPosition < length){while (myStack.size() > 0 && (int)myStack.getTop() == orderPop[popPosition] && popPosition < length){myStack.pop();popPosition++;}if(pushPosition < length){myStack.push(orderPush[pushPosition]);pushPosition ++;}if(pushPosition == length && myStack != null && (int)myStack.getTop() != orderPop[popPosition]){return false;}}return !(myStack.size() != 0);}public static void main(String[] args) {int[] push = {1,2,3,4,5};
//        int[] pop = {4,5,3,2,1};
//        int[] pop = {3,2,1,5,4};int[] pop = {4,3,5,1,2};System.out.println(validateIsPopOrder(push, pop));}
}
  • 以上两个问题都是比较复杂的问题,并且需要多个步骤分析才能得出结果,初看时候很少有思路的,这个时候,我们通过举例分析,一步一步来看,当最后一步符合,或者卡在某一个步骤时候,我们此时往往能从当前的状态看出解题的思路。

上一篇:数据结构与算法–解决问题的方法-顺时针打印矩阵
下一篇:数据结构与算法–广度优先打印二叉树

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/310411.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

优化委托的 DynamicInvoke

优化委托的 DynamicInvokeIntro委托方法里有一个 DynamicInvoke 的方法&#xff0c;可以在不清楚委托实际类型的情况下执行委托方法&#xff0c;但是用 DynamicInvoke 去执行的话会比直接用 Invoke 的方法会慢上很多&#xff0c;差了两个数量级&#xff0c;所以在知道委托类型的…

数据结构与算法-- 广度优先打印二叉树

广度优先打印二叉树 题目&#xff1a;从上往下打印出二叉树的每一个节点&#xff0c;同一层节点按照从左到右顺序打印&#xff0c;例如下图中二叉树&#xff0c;依次打印出是8,6,10,5,7,9,11 如上题中二叉树的节点定义我们用之前文章 二叉树实现原理中定义的节点结构。此处提议…

实现一个基于动态代理的 AOP

实现一个基于动态代理的 AOPIntro上次看基于动态代理的 AOP 框架实现&#xff0c;立了一个 Flag&#xff0c; 自己写一个简单的 AOP 实现示例&#xff0c;今天过来填坑了目前的实现是基于 Emit 来做的&#xff0c;后面有时间再写一个基于 Roslyn 来实现的示例效果演示演示代码&…

数据结构与算法-- 二叉树后续遍历序列校验

二叉树后续遍历序列校验 题目&#xff1a;输入一个整数数组&#xff0c;判断改数组是否是某个二叉搜索树的后续遍历结果&#xff0c;如果是返回true否则false&#xff0c;假设输入数组的任意两个数字不相同。 例如输入{5,7,6,9,11,10,8}则返回true&#xff0c;因为这个整数序列…

程序员过关斩将-- 工作好多年可能还未真正了解接口和抽象类

点击上方“蓝字”关注我们菜菜哥&#xff0c;我偷偷出去面试了&#xff0c;然后面试官让我回来等消息那你可能挂了呀&#xff0c;有什么问题没回答上来吗确实有一个问题回答的不太好哎&#xff0c;就是接口和抽象类这个确实是面试官比较爱问的题目之一那能不能说说接口和抽象类…

数据结构与索引-- mysql InnoDB存储引擎索引

索引与算法 索引是我们在应用开发过程中程序数据可开发的一个重要助力。也是一个重要的研究方向&#xff0c;索引太多&#xff0c;应用的性能可能受到影响&#xff0c;如果索引太少&#xff0c;对查询性能又会有制约。我们需要找到一个合适的平衡点&#xff0c;这个对性能至关…

扫盲消息队列 | 消息中间件 | Kafka

先吐槽我真的写技术文章写到怀疑人生&#xff0c;我翻看历史发文记录&#xff0c;只要我一本正经的写的技术文章&#xff0c;都没人看&#xff0c;但是&#xff01;一发闲扯淡的内容&#xff0c;阅读量肯定是技术文的好几倍&#xff08;读者爸爸们别这么搞嘛&#xff09;这说明…

数据结构与索引-- B+树索引

B树索引 上一节中我们讨论的都是B树的数据结构的由来以及他的一些操作&#xff0c;B树索引在本质就是B树在数据库中的一个实现&#xff0c;但是B索引在数据库中有一个特点就是他的高扇出性&#xff0c;因此在数据库中&#xff0c;B树的高度一般是2~3层&#xff0c;也就是对于查…

7种方法帮助企业改进软件维护效率

前言为了更高效地维护软件&#xff0c;同时为新的软件开发创造尽可能多的时间&#xff0c;以下为你介绍一些企业采取的方法和步骤。2019年&#xff0c;Tiedlift&#xff0c;一个开源支持和维护的企业&#xff0c;对软件开发人员进行了一项调查&#xff0c;结果显示&#xff0c;…

数据结构与索引-- mySql索引诡异事件

什么时候使用B树索引 并不是所有查询条件下出现的列都需要添加索引。对于什么时候添加索引&#xff0c;我们通过经验判断&#xff0c;访问表中很少一部分行时候&#xff0c;使用B树索引才有意义。对于性别字段&#xff0c;地区字段&#xff0c;类型字段&#xff0c;他们取值范…

[Java基础]抽象类和接口的区别

抽象类和接口的区别&#xff1a;

async,await执行流看不懂?看完这篇以后再也不会了

昨天有朋友在公众号发消息说看不懂await&#xff0c;async执行流&#xff0c;其实看不懂太正常了&#xff0c;因为你没经过社会的毒打&#xff0c;没吃过牢饭就不知道自由有多重要&#xff0c;没生过病就不知道健康有多重要&#xff0c;没用过ContinueWith就不知道await,async有…

如何分析EFCore引发的内存泄漏

调查实体框架核心中的内存泄漏不要让内存泄漏成为洪水术语“内存泄漏”和“ .NET应用程序”不是经常一起使用。但是&#xff0c;我们最近在一个.NET Core Web应用程序中出现了一系列内存不足异常。事实证明&#xff0c;此问题是由Entity Framework Core中的行为更改引起的&…

数据结构与算法-- 二叉树中和为某一值的路径

二叉树中和为某一值的路径 题目&#xff1a;输入一颗二叉树和一个整数&#xff0c;打印出二叉树中节点值的和为给定值的所有路径。从树的根节点开始往下一只到叶子节点所经过的节点形成一条路径。我们用二叉树节点的定义沿用之前文章中 二叉查找树实现原理定义。如下&#xff…