入栈、出栈顺序匹配

  • 前言
  • 一、Java入栈、出栈
    • 1、例题
    • 二、题解
      • A.纯正的模拟
      • B.LinkedHashSet
      • C.利用CPU
  • 总结
  • 参考文献

前言

给出入栈顺序,匹配一个出栈顺序是否合法,即出栈入栈一定要满足先进后出的特定。

一、Java入栈、出栈

1、例题

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

示例 1:
输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
示例 2:
输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出:false
解释:1 不能在 2 之前弹出。

二、题解

A.纯正的模拟

思想)根据栈的特点后进先出和出栈序列,来模拟什么时候入栈和出栈,通过set来记录以前是否入栈过,再通过栈顶元素是否相等来模拟入栈和出栈。

public boolean validateStackSequences3(int[] pushed, int[] popped) {//map来记录是否被压入到前面出不来,用栈结构来模拟入栈出栈Set<Integer> mark = new HashSet<>();Deque<Integer> stack = new ArrayDeque<>();int i = 0, j = 0;//模拟while (j != popped.length) {if (stack.isEmpty() || i < pushed.length && stack.peek() != popped[j]) {stack.push(pushed[i]);mark.add(pushed[i]);i++;}if(stack.peek() == popped[j]){stack.pop();mark.remove(stack.peek());j++;}else if(mark.contains(popped[j]))return false;}return true;}

B.LinkedHashSet

用set来记录,linkedlist来模拟栈,将两个融合在一起就是LinkedHashSet。

public boolean validateStackSequences2(int[] pushed, int[] popped) {//map来记录是否被压入到前面出不来,用栈结构来模拟入栈出栈Set<Integer> mark = new LinkedHashSet<>();int i = 0, j = 0;//模拟while (j != popped.length) {if (pushed[i] == popped[j]) {i += i == pushed.length - 1 ? 0 : 1;j++;} else if (mark.isEmpty() || (int) mark.toArray()[mark.size() - 1] != popped[j] && !mark.contains(popped[j])) {mark.add(pushed[i]);i += i == pushed.length - 1 ? 0 : 1;;} else if ((int) mark.toArray()[mark.size() - 1] != popped[j] && mark.contains(popped[j]))return false;else {mark.remove(popped[j]);j++;}}return true;}

C.利用CPU

上面的模拟,太过于刻板,有太多的if else if,这样的选择会使CPU利用率下降。CPU最擅长的就是计算,不用set记录一些元素是否入栈过。
思想)一旦不相等或栈空,就入栈元素;(不用管出栈序列元素是否在低端无法出栈)一旦相等就出栈然后再比较栈顶元素是否和下一个需出栈的元素相等。

public boolean validateStackSequences(int[] pushed, int[] popped) {//map来记录是否被压入到前面出不来,用栈结构来模拟入栈出栈Deque<Integer> stack = new ArrayDeque<>();int i = 0;//模拟for(int num : pushed){stack.push(num);while(!stack.isEmpty() && stack.peek() == popped[i]){stack.pop();i++;}}return stack.isEmpty();}

总结

1)刻板模拟,CPU利用率不高。
2)不用每次比较完是否相等都去判断一下该元素是否被压在低端而导致无法出栈。

参考文献

[1] Leetcode 原题
[2] Leetcode 解答

Java之根据入栈顺序是否能得到出栈顺序相关推荐

  1. 1.栈的压栈(入栈、进栈)及出栈 2.顺序表及链表的缓存命中

    一.栈的压栈(入栈.进栈)及出栈 1.栈 1.1栈的概念及结构 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作.进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底.栈中的数据元素 ...

  2. 已知入栈顺序求所有的出栈顺序已知出栈顺序求所有的入栈顺序

    一.已知入栈顺序求所有的出栈顺序 已知入栈顺序是{1,2,3,4,5},求所有的出栈顺序? 我的思路: 既然入栈顺序固定,我觉得可以使用递归来做. 先定义一个函数,比如说叫做help. //伪代码 v ...

  3. 大话数据结构第四章栈的基本概念与出栈入栈操作

    一.栈的顺序存储结构 1.基本概念 栈顶就是表尾. 栈顶是栈插入和删除的地方. 栈就是只允许在表尾进行添加或删除,是顺序存储结构线性表的特例或者说简化. 为什么说是简化呢?相对于顺序存储结构来说栈只允 ...

  4. 在堆栈中,push为入栈操作,pop为出栈操作

    LinkedList提供以下方法:(ArrayList无此类方法) addFirst(); removeFirst(); addLast(); removeLast(); 在堆栈中,push为入栈操作 ...

  5. 栈 - 关于出栈序列,判断合法的出栈序列

    文章目录 1 引例 2 做题方法 3 原因 3.1 选项D(4 3 1 2)的模拟 1 引例 (例)设栈的入栈序列是 1 2 3 4,则下列不可能是其出栈序列的是( ). A. 1 2 4 3 B. ...

  6. 数据结构实验之栈与队列七:出栈序列判定

    Description 给一个初始的入栈序列,其次序即为元素的入栈次序,栈顶元素可以随时出栈,每个元素只能入栈依次.输入一个入栈序列,后面依次输入多个序列,请判断这些序列是否为所给入栈序列合法的出栈序 ...

  7. 详解+G - 数据结构实验之栈与队列七:出栈序列判定

    理解: 出入栈规律之一,如果前面有一个比较大的数,后面有连续的递增顺序,递增顺序>=2个小于前面比较大的数,那么此出栈顺序不可能实现.比如4,1,2,3,5. 思路:输入一个数,然后不断按照顺序 ...

  8. ABCDE-入栈,不可能的出栈次序

    ABCDE 入栈,不可能的出栈次序是? 实际上最简单的办法是用笔记录一下 比如验证CDEBA的顺序可不可能,那么C先出栈于是栈应该是 C (先压入3,再弹出4) B (压入2) A (压入1) 然后弹 ...

  9. 1.若元素的进栈序列为:A、B、C、D、E,则:运用栈操作,能否得到出栈序列B、C、A、E、D和D、B、A、C、E?为什么?

    初学数据结构,有一些有意思的东西就写出来记录一下 这个是上课的时候老师出的课堂考试题目,觉得很有意思,分享给大家. 初看题目的时候,第一反应是栈是先进后出,那出栈顺序不就只有一种(E.D.C.B.A) ...

最新文章

  1. HiCar SDK概述
  2. PHP ORM框架ezpdo(2)之EZPDOSQL
  3. tar:file-changed-as-we-read-it报错处理
  4. Chat Ban 二分,等差数列(1300)
  5. bs cs架构区别_ehr系统是选择BS还是CS 架构?
  6. 小程序开发学习(2)---.wxml详解篇
  7. Linux——VIM中代码的折叠和打开
  8. 这可能是国内首款5G手机了!中兴AXON 10 Pro 5G上市定档
  9. uploadify 上传时丢失session
  10. My 1st webUI try
  11. WPS调整一页中打印多页的设置使页码顺序正确
  12. 1、NetBIOS简介
  13. Serverless 应用引擎 SAE 携手谱尼测试共同抗疫
  14. 【论文笔记】RS--基于卫星遥感的中国县级尺度小麦估产研究
  15. 关系数据库范式(1NF,2NF,3NF,BCNF,4NF,5NF)全解析
  16. 微信小程序如何实现上拉刷新(即分页加载数据)?
  17. 微型计算机音节,二年级微机下册教案
  18. 当程序员这么多年,我学到了25条人生经验
  19. python agg函数_dataframe转化(二)之 apply(),transform(),agg() 的用法和区别
  20. 最全MyBatis核心配置文件总结:java运行环境没有安装或配置错误

热门文章

  1. ThinkPad R400 windows 2008 下网卡、蓝牙驱动程序安装过程记录
  2. 小程序源码商城,如果找到一套合适的商城源码
  3. 【转】程序员的职业生涯该如何过——前锤子科技研发总监池建强
  4. Android UI开发第四篇——实现像handcent sms或者chomp sms那样的气泡短信样式
  5. Java中的锁机制 -- 乐观锁、悲观锁、自旋锁、可重入锁、读写锁、公平锁、非公平锁、共享锁、独占锁、重量级锁、轻量级锁、偏向锁、分段锁、互斥锁、同步锁、死锁、锁粗化、锁消除
  6. git合并分支产生冲突解决方案
  7. Python编程 从入门到实践——第1章 起步
  8. 另类数据的崛起——CnOpenData在行动(下)
  9. 面向对象设计原则:开闭原则(OCP)
  10. ubuntu 启动时,加载后自动进入emergence mode