思路是單調棧
比如輸入[1,3,2],初始dot = 0, ans = 0。
首先,1入棧,dot += 1 * 1
,這個加上的1對應區間為[1],ans += dot, ans = 1
然後,3入棧,dot += 3 * 1
,即dot = 4 = 1 + 3
,這裡的1對應的區間為[1, 3], 3對應的區間為[3],ans += dot,ans = 1 + (1 + 3)
,對應的區間為[1], [1,3], [3]
最後,2入棧前將3彈出棧,彈出的時候dot -= 3 * 1, dot = 1
,這個剩下的1對應區間是[1,3],被減去的3代表區間[3],因為[3,2]的最小值將變為2,而不是3。2入棧時,count = 2,即兩個區間[3,2],[2]的最小值都是2。dot += 2 * 2,dot = 1 + 2 + 2
,對應的區間為[1,3,2], [3,2], [2],ans += dot, ans = 1 + (1 + 3) + (((1 + 3) - 3) + 2 + 2) = 1 + (1 + 3) + (1 + 2 + 2)
。對應區間為[1], [1,3], [3],[1,3,2],[3,2],[2]
換句話說,count
始終維護了,以當前index的數值a[index]
為最小值的區間個數,dot
維護了以a[:index]
中為最小值的區間的和。
class
solution
:def
sumsubarraymins
(self, a: list[
int])-
>
int:
mod =
10**9+
7 stack =
# 迴圈中表示含有當前數字的數字的,最小值之和。未必當前數字是最小值
doc =
0 res =
0for i in
range
(len
(a))
: count =
1while stack and stack[-1
][0]
>=a[i]
: cur, num = stack.pop(
)# 新的值取代了老的值,以老的值作為最小值的陣列都給了當前值。
count += num
# 減去相關的陣列的最小值的和 num陣列的數量 cur 彈出的數字
doc -= num*cur
# 是乙個單調上公升的棧,前面的都會被彈出
(a[i]
, count)
)# 第一項是數值,第二項是以該數值為最小值的區間個數
# 新增上以當前數字作為最小值的數量
doc += count*a[i]
# 加上含有當前數字,但是未必是最小值的陣列的,最小值和
res += doc
res %= mod
return res
LeetCode 子陣列的最小值之和
一開始的思路是打算先求出所有子陣列,然後排序子陣列,最後相加,然而運算太複雜,會超出時間限制 sumsubarraymins arr for let k 0 k allarr.length k res allarr k 0 console.log allarr console.log res 後來改...
907 子陣列的最小值之和
碰到leetcode907,子陣列的最小值之和,用python3按自己思路寫死都過不去,怎麼都超時,這是python3 class solution def sumsubarraymins self,a type a list int rtype int res 0 length len a for...
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...