Java数据结构与算法——单调栈算法笔记

文章目录

  • 一、单调栈的定义及特点
  • 二、案例
      • 案例一:柱状图中最大的矩形
      • 案例二:每日温度
      • 案例三:下一个更大元素 I

一、单调栈的定义及特点

所谓单调栈就是在栈先进后出的特性之外再添加一个特性:从栈顶到栈底的元素严格递增(or递减)。

  • 栈内元素保持单调,有单调递增栈和单调递减栈。注意:这里的单调递增或递减指的是从栈顶到栈底单调递增或递减。
  • 每个元素都要入栈,且仅入栈一次,出栈后不再入栈。
  • 注意:栈内可以直接存储元素,也可以存储元素的索引,一般存储的是索引。当存储的是索引时,是说索引对应的元素是单调的,而不是说索引是单调的。
  • 操作规则(以单调递增栈为例,单调递减栈相反):设当前进栈元素为 e,如果 e 小于栈顶元素,就直接入栈;如果 e 大于或等于栈顶元素,那就一直弹栈,直到栈顶元素大于 e 或者栈为空时,再将 e 入栈。

举个例子:

单调递增栈为例,现有一组数 array = {3,4,2,6,4,5,2,3},该数组元素入栈的过程如下(注意:入栈的是索引,这里为了看的更直观,把元素值标注在括号内):

  • 从左往右依次入栈;
  • 刚开始栈为空,3 直接入栈,得到
    |0(3)|
  • 下一个元素 4 > 栈顶元素 3,3 弹栈,4 入栈,得到
    |1(4)|
  • 下一个元素 2 < 栈顶元素 4,2 直接入栈,得到
    |2(2)|
    |1(4)|
  • 下一个元素 6 > 栈顶元素 2,2 弹栈;新的栈顶元素 4 < 6,4 继续弹栈;此时栈为空,6 入栈,得到
    |3(6)|
  • 下一个元素 4 < 栈顶元素 6,4 直接入栈,得到
    |4(4)|
    |3(6)|
  • 下一个元素 5 > 栈顶元素 4,4 弹栈,5 入栈,得到
    |5(5)|
    |3(6)|
  • 下一个元素 2 < 栈顶元素 5,2 直接入栈,得到
    |6(2)|
    |5(5)|
    |3(6)|
  • 下一个元素 3 > 栈顶元素 2,2 弹栈,3 入栈,得到
    |7(3)|
    |5(5)|
    |3(6)|
  • 完毕。

当然,我们使用单调栈不是要求最后的栈的结果,而是利用单调栈在添加元素时的特性。

观察上面各个阶段的栈内元素,栈顶元素的底下的这一个元素,就是栈顶元素左边第一个大于该栈顶元素的元素,也就是说,当前栈顶元素弹出后,新的栈顶元素是弹出元素左边第一个大于弹出元素的元素。另外,对于当前要入栈的元素 e,如果要先弹出栈顶元素才能入栈,说明元素 e 是栈顶元素右边第一个大于该栈顶元素的元素

总结起来:

我们每次用栈顶元素参与计算,

  • 利用单调递增栈,我们能找到栈顶元素左右两边第一个大于该栈顶元素的元素
  • 利用单调递减栈,我们能找到栈顶元素左右两边第一个小于该栈顶元素的元素

二、案例

案例一:柱状图中最大的矩形

leetcode刷题(80)——84. 柱状图中最大的矩形

案例二:每日温度

leetcode刷题(45)——739.每日温度

案例三:下一个更大元素 I

leetcode刷题(82)——496. 下一个更大元素 I

你可能感兴趣的:(Java数据结构与算法,java,栈)