本题解使用单调栈的方法来找出所有子数组的最小值之和。首先,将原数组末尾添加一个0,以保证所有元素都能被正确处理。单调栈用于存储数组元素的索引,且栈中的元素对应的数组值将保持单调不增的顺序。对于每个元素,如果它小于或等于栈顶元素,那么栈顶元素及其之前的元素将依次出栈,直到栈顶元素小于当前元素。对于每个出栈的元素t,计算以arr[t]为最小值的子数组的数量,乘以arr[t],再累加到结果中。这样,每个元素在出栈时,可以算出以它为最小值的所有连续子数组对结果的贡献。最终,返回累加的结果,对1,000,000,007取模。
时间复杂度: O(n)
空间复杂度: O(n)
class Solution:
def sumSubarrayMins(self, arr: List[int]) -> int:
mod = 1_000_000_007 # 定义模数
s = [-1] # 初始化栈,用-1作为哨兵元素
arr.append(0) # 将0添加到数组末尾,以处理所有元素
ans = 0 # 初始化结果累加器
for idx, i in enumerate(arr): # 遍历数组及其索引
while i <= arr[s[-1]]: # 当当前元素小于等于栈顶元素时
t = s.pop() # 弹出栈顶元素
if t == -1: # 如果栈为空则直接返回结果
return ans
ans = (ans + arr[t] * (t-s[-1]) * (idx-t)) % mod # 计算以arr[t]为最小值的子数组的贡献,并累加到结果中
s.append(idx) # 将当前索引压入栈