Day63 单调栈part02

LC42接雨水(未掌握

  1. 暴力解法:按列求雨水体积
  • 宽度一定是1
  • 高度,取决于,该列 左侧最高的柱子和右侧最高的柱子中最矮的那个柱子的高度。
    在这里插入图片描述
  • 代码
    在这里插入图片描述
  1. 双指针优化法:
  • 每到一个柱子都向两边遍历一遍,这其实是有重复计算的。
  • 我们把每一个位置的左边最高高度记录在一个数组上(maxLeft),右边最高高度记录在一个数组上(maxRight),这样就避免了重复计算
  • 代码
    在这里插入图片描述
  1. 单调栈
  • 需要寻找一个元素,右边最大元素以及左边最大元素,来计算雨水面积
  • 单调栈从栈头到栈底的顺序是从小到大的
  • 一旦发现添加的柱子高度大于栈头元素了,此时就出现凹槽了,栈头元素就是凹槽底部的柱子,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子。
  • 遇到相同高度的柱子需要使用最右边(最后出现)的柱子来计算宽度
  • 单调栈是按照行方向来计算雨水
    在这里插入图片描述
  • 情况分析
    • 当前遍历的元素(柱子)高度小于栈顶元素的高度 height[i] < height[st.top()]=》入栈
    • 当前遍历的元素(柱子)高度等于栈顶元素的高度 height[i] == height[st.top()]=》栈顶出栈,入栈
    • 当前遍历的元素(柱子)高度大于栈顶元素的高度 height[i] > height[st.top()]
      • 栈顶出栈记为mid
      • 寻找出栈后栈顶元素和当前元素的最小值
      • 高度为最小值减mid,宽度为i-栈顶元素-1
      • while循环判断下一个
  • 代码
    • while
    • while之后别忘记stack.push(i)
      在这里插入图片描述

LC84柱状图中最大的矩形

  1. 跟LC42接雨水一样,都可以分为三种方法
  2. 暴力:按列求,找到每个柱子左侧连续的第一个比本身小的柱子和右侧连续的第一个比本身小的柱子
  • 不同的地方在于:左侧或者右侧最高的柱子需要与判断的柱子连续,因不符合的情况需要break
  1. 代码
    在这里插入图片描述
  2. 双指针方法
  • 不一样的地方在于:要记录记录每个柱子 左边第一个小于该柱子的下标,而不是左边第一个小于该柱子的高度。
  • i柱子
    • 如果i左边的柱子t比i柱子高度高(等于),那left[t]对应的柱子一定也比i柱子高,因此需要使用while循环
    • 如果i左边的柱子t比i柱子高度矮(等于),那left[i]=t
    • 如果i右边的柱子t比i柱子高度高(等于),那right[t]对应的柱子一定也比i柱子高,因此需要使用while循环
    • 如果i右边的柱子t比i柱子高度矮(等于),那right[i]=t
  1. 代码
  • left[0]初始化为-1
  • right[height.length-1]初始化为height.length
    在这里插入图片描述
  1. 单调栈
  • 本题是要找每个柱子左右两边第一个小于该柱子的柱子,所以从栈头(元素从栈头弹出)到栈底的顺序应该是从大到小的顺序!
  • 栈顶和栈顶的下一个元素以及要入栈的三个元素组成了我们要求最大面积的高度和宽度
  • 情况分析
    • 当前遍历的元素大于栈顶元素heights[i]>heights[st.top()]=》入栈
    • 当前遍历的元素等于栈顶元素heights[i]=heights[st.top()]=》栈顶出栈,入栈
    • 当前遍历的元素小于栈顶元素heights[i]<heights[st.top()]
      • 栈顶出栈记为mid
      • 出栈后栈顶元素和当前元素进行求一次矩阵面积
      • 高度为height[mid],宽度为i-栈顶元素-1
      • while循环判断下一个
  1. 代码
  • while
  • while之后别忘记stack.push(i)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值