907. 子数组的最小值之和

考虑所有满足以数组 \textit{arr}arr 中的某个元素 \textit{arr}[i]arr[i] 为最右且最小的元素的子序列个数 C[i]C[i],那么题目要求求连续子数组的最小值之和即为 \sum_{i=0}^{n-1} \limits \textit{arr}[i] \times C[i]
i=0

n−1

arr[i]×C[i],其中数组 \textit{arr}arr 的长度为 nn。我们必须假设当前元素为最右边且最小的元素,这样才可以构造互不相交的子序列,否则会出现多次计算,因为一个数组的最小值可能不唯一。

经过以上思考,我们只需要找到每个元素 \textit{arr}[i]arr[i] 以该元素为最右且最小的子序列的数目 \textit{left}[i]left[i],以及以该元素为最左且最小的子序列的数目 \textit{right}[i]right[i],则以 \textit{arr}[i]arr[i] 为最小元素的子序列的数目合计为 \textit{left}[i] \times \textit{right[i]}left[i]×right[i]。当然为了防止重复计算,我们可以设 \textit{arr}[i]arr[i] 左边的元素都必须满足小于等于 \textit{arr}[i]arr[i],\textit{arr}[i]arr[i] 右边的元素必须满足严格小于 \textit{arr}[i]arr[i]。当然这就变成求最小的下标 j \le ij≤i,且连续子序列中的元素 \textit{arr}[j], \textit{arr}[j+1], \cdots, \textit{arr}[i]arr[j],arr[j+1],⋯,arr[i] 都满足大于等于 \textit{arr}[i]arr[i],以及最大的下标 k > ik>i 满足连续子序列 \textit{arr}[i + 1], \textit{arr}[i+1], \cdots, \textit{arr}[k]arr[i+1],arr[i+1],⋯,arr[k] 都满足严格大于 \textit{arr}[i]arr[i]。上述即转化为经典的单调栈问题,即求数组中当前元素 xx 左边第一个小于 xx 的元素以及右边第一个小于等于 xx 的元素,关于「单调栈」的算法细节,可以参考「496. 下一个更大元素 I 题解」。

对于数组中每个元素 \textit{arr}[i]arr[i],具体做法如下:

求左边第一个小于 \textit{arr}[i]arr[i] 的元素:从左向右遍历数组,并维护一个单调递增的栈,遍历当前元素 \textit{arr}[i]arr[i],如果遇到当前栈顶的元素大于等于 \textit{arr}[i]arr[i] 则将其弹出,直到栈顶的元素小于 \textit{arr}[i]arr[i],栈顶的元素即为左边第一个小于 \textit{arr}[i]arr[i] 的元素 \textit{arr}[j]arr[j],此时 \textit{left}[i] = i - jleft[i]=i−j。

求右边第一个大于等于 \textit{arr}[i]arr[i] 的元素:从右向左遍历数组,维护一个单调递增的栈,遍历当前元素 \textit{arr}[i]arr[i],如果遇到当前栈顶的元素大于 \textit{arr}[i]arr[i] 则将其弹出,直到栈顶的元素小于等于 \textit{arr}[i]arr[i],栈顶的元素即为右边第一个小于等于 \textit{arr}[i]arr[i] 的元素 \textit{arr}[k]arr[k],此时 \textit{right}[i] = k - iright[i]=k−i。

连续子数组 \textit{arr}[j], \textit{arr}[j + 1], \cdots, \textit{arr}[k]arr[j],arr[j+1],⋯,arr[k] 的最小元素即为 \textit{arr}[i]arr[i],以 \textit{arr}[i]arr[i] 为最小元素的连续子序列的数量为 (i - j) \times (k - i)(i−j)×(k−i)。

根据以上结论可以知道,所有子数组的最小值之和即为 \sum_{i=0}^{n - 1} \limits \textit{arr}[i] \times \textit{left}[i] \times \textit{right}[i]
i=0

n−1

arr[i]×left[i]×right[i]。维护单调栈的过程线性的,因为只进行了线性次的入栈和出栈。

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/sum-of-subarray-minimums/solution/zi-shu-zu-de-zui-xiao-zhi-zhi-he-by-leet-bp3k/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值