题目

一个含有重复值的数组arr,找到每一个i位置左边和右边离i位置最近且值比arr[i]小的位置,返回所有相应的信息。

举例:arr={3,4,1,5,6,2,7},返回如下的二维数组作为结果:{{-1,2},{0,2},{-1,-1},{2,5},{3,5},{2,-1},{5,-1}},其中-1表示不存在


要求

如果arr长度为N,时间复杂度达到O(N)。


思路

数据结构:单调栈,依旧存放数组元素的索引,但是因为会存在重复的数字,如果依旧和初阶问题一样直接存索引的话,会存在问题,所以栈里存放列表,列表里存放索引,相同的索引存在同一个列表中

使用一个栈,并且使该栈从栈顶到栈底的值是严格递减的(因为找的是左右两边比当前位置小的值)。

流程:

  1. 遍历数组
  2. 栈为空或者当前arr[i]大于栈顶中列表的第一个元素(因为同一个列表中存放的索引值不同但是对应的数组值都是一样的)对应的数组值,直接新建一个列表,将当前i加入列表并入栈
  3. 若栈不为空,并且当前arr[i]小于栈顶列表中第一个元素 j(假设为j,因为栈里存放的是数组索引值,这里比较的是arr[i]<arr[j]),则需要弹出栈顶元素(即弹出一个列表),则对于弹出列表中最后插入的元素j来说左边位置离j最近并且小于arr[j]的值为当前栈顶对应的值,右边位置则是i;
  4. 若栈不为空,并且当前arr[i]小于栈顶列表中第一个元素 j(假设为j,因为栈里存放的是数组索引值,这里比较的是arr[i]=arr[j]),如果两个值相等则将当前i,直接加入当前栈顶列表。
  5. 遍历完数组后,若栈不为空,则对于栈中的所有元素,它们的右边位置最近并且小于他们的值都不存在即为-1;依次弹出栈顶列表,并对列表中的元素 (假设为j)迭代循环,j的右边为-1,左边位置为当前栈顶列表中最后插入的值;完成

源码

public int[][] getNearLess(int[] arr){//初始化结果数组int[][] res=new int[arr.length][2];//初始化单调栈Stack<List<Integer>> stack=new Stack<>();//遍历数组for(int i=0;i<arr.length;i++){//若栈不为空,并且当前数组值小于栈顶列表中第一个元素所对应的数组值while(!stack.isEmpty()&&arr[stack.peek().get(0)]>arr[i]){//弹出栈顶的列表List<Integer> popIndex=stack.pop();//取列表中加入最晚的int leftLessIndex=stack.isEmpty()?-1:stack.peek().get(stack.peek().size()-1);int rightLessIndex=i;for(Integer popi:popIndex){res[popi][0]=leftLessIndex;res[popi][1]=rightLessIndex;}}//若栈不为空,并且当前数组值等于栈顶列表中第一个元素所对应的数组值if(!stack.isEmpty()&&arr[stack.peek().get(0)]==arr[i]){stack.peek().add(Integer.valueOf(i));}else{//若栈为空或者并且当前数组值大于栈顶列表中第一个元素所对应的数组值ArrayList<Integer> list=new ArrayList<Integer>();list.add(i);stack.push(list);}}//同初阶问题,数组遍历完后,对栈进行清洗while(!stack.isEmpty()){List<Integer> popIndex=stack.pop();int leftLessIndex=stack.isEmpty()?-1:stack.peek().get(stack.peek().size()-1);int rightLessIndex=-1;for(Integer popi:popIndex){res[popi][0]=leftLessIndex;res[popi][1]=rightLessIndex;}}return res;
}

欢迎随时交流讨论

栈与队列7——单调栈结构(进阶问题)相关推荐

  1. 栈与队列7——单调栈结构(初阶问题)

    题目 一个不含有重复值的数组arr,找到每一个i位置左边和右边离i位置最近且值比arr[i]小的位置,返回所有相应的信息. 举例:arr={3,4,1,5,6,2,7},返回如下的二维数组作为结果:{ ...

  2. 算法学习12: 单调队列和单调栈

    算法学习12: 单调队列和单调栈 单调队列 单调队列解决的问题: 窗口内最大/最小值的更新结构 单调队列的结构和操作 单调队列的应用 题目一: 生成窗口最大值数组[leetcode 239](http ...

  3. 蒟蒻的ACM数据结构(四)-单调队列和单调栈

    单调队列和单调栈 一.概念 二.实现 三.题目 单调队列 洛谷P1886 滑动窗口 解析 单调栈 [GXOI/GZOI2019]与或和 解析 POJ3250 Bad Hair Day 解析 POJ 2 ...

  4. 【数据结构】栈和队列OJ练习(栈和队列相互实现+循环队列实现)

    目录 前言 1.用队列实现栈 2.用栈实现队列 3.循环队列 前言 前面在学习了栈和队列的实现之后,相信大家对栈和队列的结构和使用方式都有了一些理解. 下面我们就来进行一些练习,这这章的练习相对于原来 ...

  5. sdut 3335 数据结构实验之栈与队列八:栈的基本操作

    数据结构实验之栈与队列八:栈的基本操作 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Descri ...

  6. 算法竞赛入门与进阶 (二)单调队列、单调栈

    栈(stack)和队列( queue ) 1.栈的定义:栈是限定仅在表头进行插入和删除操作的线性表(先进后出) 2.队列的定义:队列是一种特殊的线性表,特殊之处在于 它只允许在表的前端(front)进 ...

  7. 单调队列,单调栈总结

    最近几天接触了单调队列,还接触了单调栈,就总结一下. 其实单调队列,和单调栈都是差不多的数据类型,顾名思义就是在栈和队列上加上单调,单调递增或者单调递减.当要入栈或者入队的时候,要和栈头或者队尾进行比 ...

  8. 栈和队列都是什么结构_数据结构与算法之初识栈与队列

    栈和队列 学习目标 本节我们将初步认识栈和队列,栈和队列是限定插入和删除只能在表的"端点"进行的线性表. 开始学习 01栈 是什么? 限定仅在表尾进行插入和删除操作的线性表,表尾- ...

  9. Java数据结构(1.1):数据结构入门+线性表、算法时间复杂度与空间复杂度、线性表、顺序表、单双链表实现、Java线性表、栈、队列、Java栈与队列。

    数据结构与算法入门 问题1:为什么要学习数据结构          如果说学习语文的最终目的是写小说的话,那么能不能在识字.组词.造句后就直接写小说了,肯定是不行的, 中间还有一个必经的阶段:就是写作 ...

最新文章

  1. java中if结构用图表示_Java语法基础之选择结构的if语句、switch语句详解
  2. 项目中的那些事---下载pdf文件
  3. html中单选框颜色怎么改,如何更改单选按钮的颜色?
  4. CF1271D Portals
  5. JavaFX技巧20:有很多需要展示的地方吗? 使用画布!
  6. linux mmap 内存映射 mmap() vs read()/write()/lseek()
  7. winform教_电脑绝技教你22天学精Csharp之第十五天winform应用程序补充5
  8. python解压缩gz文件_使用python解压缩.gz文件的一部分
  9. C++ 布隆过滤器原理及实现
  10. 大二下周总结(14)
  11. 在 Linux 上如何清除内存的 Cache、Buffer 和交换空间
  12. nowcoder 合并回文子串
  13. javascript在firefox中对Dom的处理的一个问题
  14. linux根文件系统的挂载过程详解
  15. Tcp ip 网络编程入门(一)
  16. 65位高校教师接龙晒工资,全国各地高校,给打算入高校的博士们参考!
  17. 自定义结构体及初始化
  18. Unity3D射击游戏的准心
  19. nu.xom:Document
  20. php if相关标签,dedecms模板中运用dede标签时使用php和if判断语句的方法

热门文章

  1. 从YOLOv1到YOLOv3,目标检测的进化之路
  2. 干货 | 目标检测入门,看这篇就够了(下)
  3. 详解CPU漏洞对机器学习的影响:几乎所有卷积层都受影响,QR分解降速37%
  4. IDEA 新特性:提前知道代码怎么走
  5. 探索常见的几种限流策略和实现
  6. 【廖雪峰python入门笔记】布尔运算和短路计算
  7. 万物皆可embedding,AI 应用神器 Milvus 登顶数据库顶会 SIGMOD
  8. 再见吧,996!程序员开源考公指南获高赞:三人已成功上岸
  9. Transformer 又立功了!又快(420 fps)又好的车道线检测算法
  10. 自动驾驶领域大佬在CVPR2020中 关于3D Reconstruction Learning的报告