单调栈-下
class53单调栈-下
除了单调栈最经典的用法之外,在很多问题里单调栈还可以 维持求解答案的可能性
- 单调栈里所有的对象按照规定好的单调性来组织(小压大等)
- 当某个对象进入单调栈时,会从栈顶开始淘汰单调栈内对后续求解答案没有帮助的对象
- 每个对象从栈顶弹出的时候结算当前对象参与的答案,随后这个对象不再参与后续求解答案的过程
题目1
测试链接:962. 最大宽度坡
做法:
- 维护一个单调栈,存放答案可能的左边界,用小压大实现
- 从后往前遍历数组(
int j = n - 1),假定当前位置为答案的右边界,依次与栈顶元素比较,如果满足宽度坡,记录答案,淘汰栈顶元素,继续与栈中下一个元素比较,如果不满足宽度坡,j--,重复上述操作
代码
1 | class Solution { |
题目2
题目链接:316. 去除重复字母
做法
- 维护一个单调栈,遵循大压小,维护一个词频数组,记录个字符出现的次数,维护一个
enter数组,记录字符是否在栈中 - 遍历字符串,如果栈中有元素,且栈顶元素大于当前元素且栈顶元素词频不为0,弹出栈顶元素,继续判断直至栈顶元素小于当前元素,将当前元素入栈,词频减1,入栈数组置为
true
代码
1 | class Solution { |
题目3
题目链接:大雨吃小鱼牛客题霸牛客网
做法
- **维护一个单调栈,遵循小压大,栈中存储 **
(鱼的体积, 吞并所需操作次数) - 从右向左遍历数组,对每个元素:
- 弹出所有比当前鱼小的栈顶元素
- 更新当前鱼的吞并次数:
curTurns = max(curTurns + 1, 弹出元素的吞并次数) - 将当前鱼及其吞并次数压入栈
- 全局最大吞并次数即为答案
代码
1 | import java.util.*; |
题目4
做法
-
**将二维问题转换为一维问题,对于每一行 **
i,我们维护一个height数组,其中height[j]表示从当前行向上连续的1的个数(即以第i行为底,第j列的高度) -
对每行的高度数组,统计以该行为底的全 1 子矩形数量
-
- 左边界:栈中前一个元素(栈空为-1)
- 右边界:当前元素k
- 长度:
k - left - 1; - 有效范围:
(height[cur] - bottom),其中bottom是左右边界中的较大值,在这个范围内,可以形成(height[cur] - bottom) * len * (len + 1) / 2个子矩形。
为什么是
len \* (len + 1) / 2? **因为在长度为 **len的连续区间中,有len个长度为 1 的子区间,len-1个长度为 2 的子区间,…,1 个长度为len的子区间,总和为len * (len + 1) / 2。
代码
1 | class Solution { |
本文是原创文章,采用CC BY-NC-SA 4.0协议,完整转载请注明来自Heaven
