今天是一道中等题,
题目:
我看到这个3*1e4就知道不能用暴力解法,但是还是没忍住试了下!
class Solution:
def sumSubarrayMins(self, arr: List[int]) -> int:
l=len(arr)
nums=0
for i in range(l):
if i==l-1:
return int((nums+arr[i])%(1e9+7))
minc=arr[i]
nums+=minc
for j in range(i+1,l):
minc=min(minc,arr[j])
nums+=minc
return int(nums%(1e9+7))
果然!
只能用其他方法啦
单调栈的算法思想:
求出每一个元素向左右衍生的最长的且最小值是他自己的连续序列
-求左边界
--从左向右遍历数组,若为空栈或者此元素大于栈顶元素,则入栈,并且标记该元素的左边界就是栈顶元素的下标(空栈返回-1),否则入栈
--求右边界
--思想差不多,只不过是空栈的话标记n
最后求每个元素的左右边界乘积再乘该元素的值相加,大于MOD则减去MOD,比%运算更省时间!
代码:
MOD = 10 ** 9 + 7
class Solution:
def sumSubarrayMins(self, arr: List[int]) -> int:
n = len(arr)
monoStack = []
left = [0] * n
right = [0] * n
for i, x in enumerate(arr):
while monoStack and x <= arr[monoStack[-1]]:
monoStack.pop()
left[i] = i - (monoStack[-1] if monoStack else -1)
monoStack.append(i)
monoStack = []
for i in range(n - 1, -1, -1):
while monoStack and arr[i] < arr[monoStack[-1]]:
monoStack.pop()
right[i] = (monoStack[-1] if monoStack else n) - i
monoStack.append(i)
ans = 0
for l, r, x in zip(left, right, arr):
ans = ans + l * r * x
if ans>=MOD:#取模运算比这个运算更耗时间
ans-=MOD
return ans
运行结果:![](https://i-blog.csdnimg.cn/blog_migrate/e8427541b87ea85cbcc86fe1cfe1a678.png)
今天的每日一题拿下!