单调栈-拓展应用

907. 子数组的最小值之和

2104. 子数组范围和

 

本篇文章主要分析一下两个题目,这两个题目都是利用单调栈解决问题!!关于单调栈详细介绍可见 单调栈

子数组的最小值之和

题目详情可见 子数组的最小值之和

题目的原问题:求每个子数组中最小值之和

我们不妨可以把问题稍微转换一下,如果我们知道以某一个元素为最小值的所有子数组数量,那么该元素的贡献值就是val * n

现在我们需要解决的是怎么得到某一个元素的覆盖范围呢??

注意:

做好了上述准备数据后,我们如何求满足数量呢??

很简单,分别求出「以i结尾的子数组数量」和「以i开头的子数组数量」

即:num = (i - left) * (right - i)

因为(left, right)是开区间,所以不需要+1

详细过程如下图所示:

6

基于前文介绍的单调栈,我们都是一边一边的求,即:先求下一个更小的元素,再求上一个更小的元素

其实可以一次循环同时把「下一个更小的元素,上一个小于等于的元素」求出来

下面给出一次循环同时求出两个的模版:

基于这个模版,我们可以给出这个题目详细代码:

子数组范围和

题目详情可见 子数组范围和

这个题目解决思路和上面的题目如出一辙!

求出以某一个元素为最小值的所有子数组数量,记为 min;再求出以该元素为最大值的所有子数组数量,记为 max

所以该元素的贡献值为:val * (max - min)

下面给出这个题目详细代码: