举例分析

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

包含min方法的栈

  • 题目:定义栈的数据结构,请在改类型中实现一个能够得到栈的最小元素min函数。在改栈中,调用min,push,pop的时间复杂度O(1)
  • 此处与普通栈不同点在于需要知道每次栈变动时候最小值。并且难点在于O(1)的时间复杂度,我们第一反应是标记最小值,这样可以在O(1)时间得到最小元素。但是最小值出栈后,次小的值就变成最小值,此时是无法获取这个值
  • 另外一个思路,每次入栈对栈中元素进行排序,这样能拿到最小值在栈首,会在尾。但是这样就违背了栈的后进先出的原则就不是栈了。
  • 分析到此处发现一个栈A并不能解决问题,我们用一个辅助的栈空间B,每次添加一个元素到A时候,将添加元素与最小元素比较(临时变量保存最小元素),将最小元素添加到B,即使最小元素没有变化仍然重复添加到B占位用。我们用如下案例分析:
步骤 操作 数据栈A 辅助栈B 最小值
1 压入3 3 3 3
2 压入6 3,6 3,3 3
3 压入4 3,6,4 3,3,3 3
4 压入45 3,6,4,45 3,3,3,3 3
5 压入0 3,6,4,45,0 3,3,3,3,0 0
6 压入2 3,6,4,45,0,2 3,3,3,3,0,0 0
  • 如上表格,我们将最小元素每次都添加到辅助栈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 压入1 1
2 压入2 1,2
3 压入3 1,2,3
4 压入4 1,2,3,4
5 弹出 1,2,3 4
6 压入5 1,2,3,5
7 弹出 1,2,3 5
8 弹出 1,2 3
9 弹出 1 2
10 弹出 1
  • 如上表格中每一个步骤操作,我们在第五步骤时候,弹出4,压入5,之后持续弹出,就能得到对应的弹出序列。
  • 我们用同样的方式来递推第二个序列
步骤 操作 弹出数字
1 压入1 1
2 压入2 1,2
3 压入3 1,2,3
4 压入4 1,2,3,4
5 弹出 1,2,3 4
6 弹出 1,2 3
7 压入5 1,2,5
8 弹出 1,2 5
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));}
}
  • 以上两个问题都是比较复杂的问题,并且需要多个步骤分析才能得出结果,初看时候很少有思路的,这个时候,我们通过举例分析,一步一步来看,当最后一步符合,或者卡在某一个步骤时候,我们此时往往能从当前的状态看出解题的思路。

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

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

  1. 【剑指offer-Java版】22栈的压入弹出序列

    栈的压入弹出序列:给定两个序列,一个是压入顺序,判断另外一个是否是该压入顺序的一个弹出顺序 思路:纯粹的模拟栈的压入和弹出顺序 分别遍历压栈序列seq1和另一个序列seq2 比较当前栈顶元素和seq2 ...

  2. 剑指offer-21.栈的压入弹出序列

    1.题目 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压 ...

  3. python 栈的压入弹出序列

    | 栈的压入和弹出序列 输入两个整数序列,第一个序列表示栈的压入顺序, 请判断第二个序列是否为该栈的弹出顺序. 假设压入栈的所有数字均不相等. 例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序 ...

  4. 剑指offer 31.栈的、压入弹出序列

    输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是 ...

  5. 算法笔记--简单实现栈的先入后出(FILO,First In Last Out)功能

    算法笔记–简单实现栈的先入后出(FILO,First In Last Out)功能 stack 栈,是一个 先入后出(FILO,First In Last Out)的 有序列表,可以形象地理解为手枪的 ...

  6. 剑指Offer(Java实现)栈的压入、弹出序列

    题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列 1,2,3,4,5 是某栈的压入顺序,序列 4,5,3,2,1 ...

  7. 举例让抽象问题具体化:栈的压入、弹出序列

    输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一 ...

  8. 面试题整理6 栈的压入、弹出序列

    <剑指offer>面试题22: 题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出序列.假设压入栈的所有数字均不相同. 例如序列1.2.3.4.5是某栈的 ...

  9. 《剑指offer》-- 栈的压入与弹出序列、把字符串转化为整数、扑克牌顺子、孩子们的游戏(圆圈中最后剩下的数)

    一.栈的压入与弹出序列: 1.题目: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序. 假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序 ...

最新文章

  1. Python 3.8 新特性全面解读
  2. build-android-in-OS-X-Yosemite-Xcode-7
  3. python语法基础知识-python基础知识---简单语法
  4. 【UML 建模】UML建模语言入门 -- 静态图详解 类图 对象图 包图 静态图建模实战
  5. (47)逆向分析 KiSystemService 函数填充 _KTRAP_FRAME 部分
  6. 加强Eclipse代码自动提示的方法
  7. git 工具_Github开源工具分享之自托管GIT服务工具Gogs
  8. VistaDB 数据库,.NET的新选择
  9. java字符串常量池——字符串==比较的一个误区
  10. mysql数据库的字符集_mysql数据库中字符集乱码问题原因及解决
  11. PHP点歌插件,斗鱼弹幕点歌插件_小葫芦社区_小葫芦插件交流 - Powered by Discuz!
  12. java实现折半查找_java语言之实现折半查找算法
  13. 看完上汽制动的数字化,才发现以前的数据可视化大屏都白做了
  14. 计算机初级技能词,计算机领域英语常用词汇初级.doc
  15. Ubuntu 搭建SVN服务器(SVN Server)
  16. Python数据分析:数据可视化案例
  17. 计算机网络知识点及例题总结(五)数据链路层与局域网
  18. 开源项目 - 电子签章(移动端签名方案)
  19. 交叉编译Qt5.9.6
  20. 《机器学习》(周志华)线性回归

热门文章

  1. SSH基本原理和免密码登录
  2. python数据分析软件_Python数据分析工具
  3. 王道408数据结构——第四章 串(KMP算法)
  4. 博导眼里本科生的科研能力:“他们还在玩泥巴”
  5. 批作业是小学老师的一大乐趣 | 今日最佳
  6. 老是担心数学学不好?是因为你的数学老师不是爱因斯坦!
  7. 入门机器学习,开启人工智能大门!
  8. 毕业的那天,程序员师兄竟然让我去做这一行
  9. 如何撬动机器学习的冰山一角?
  10. Spark的基本架构