leecode 907. 子数组的最小值之和
给定一个整数数组 arr,找到 min(b) 的总和,其中 b 的范围为 arr 的每个(连续)子数组。
由于答案可能很大,因此 返回答案模 10^9 + 7 。
示例 1:
输入:arr = [3,1,2,4]
输出:17
解释:
子数组为 [3],[1],[2],[4],[3,1],[1,2],[2,4],[3,1,2],[1,2,4],[3,1,2,4]。
最小值为 3,1,2,4,1,1,2,1,1,1,和为 17。
示例 2:
输入:arr = [11,81,94,43,3]
输出:444
class Solution:
def sumSubarrayMins(self, arr: List[int]) -> int:
sum = 0
if len(arr) == 1:
return arr[0]%1000000007
for i in range(1,len(arr)+1):
for j in range(len(arr)):
if (i+j) <= len(arr):
sum+=min(arr[j:j+i])
return (sum%1000000007)
我的思路
首先找到数组长度为1的特殊情况。然后使用嵌套循环,外层循环控制截取子数组的长度,比如arr数组的总长度是4,则子数组的长度有1,2,3,4。所以外部循环用来控制子数组的长度,内部数组用来截取对应长度的数组并取最小值,加到sum里,这里要注意一下循环的次数。
这种思路得到的所有用例的结果是正确的,但是再最后长数组,大数字的用例中,结果正确但是超时了。
题解的思路
看到题解,大家都是用单调栈,还是第一次听说,有时间仔细研究一下。
class Solution:
def sumSubarrayMins(self, arr: list[int]) -> int:
q = []
ans = curSum = 0
for num in arr:
cnt = 1
while q and num <= q[-1][0]:
cnt += q[-1][1]
curSum -= q[-1][0] * q[-1][1]
q.pop()
q.append((num, cnt))
curSum += q[-1][0] * q[-1][1]
ans += curSum
return ans % (10 ** 9 + 7)
作者:sodaman