單調棧-907. 子陣列的最小值之和
阿新 • • 發佈:2022-05-25
2022-05-25 21:40:29
問題描述:
給定一個整數陣列 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
提示:
1 <= arr.length <= 3 * 104
1 <= arr[i] <= 3 * 104
問題求解:
本題需要考慮每個元素的管轄範圍:對應nums[i]以其為最小值的範圍[l, r]。
這一步可以通過單調棧求得。
但有一點需要特別注意:去重。
這裡的去重邏輯是採用單邊邏輯,例如取左邊第一個小於nums[i]的位置,取右邊第一個小於等於nums[i]的位置。
class Solution: def sumSubarrayMins(self, arr: List[int]) -> int: n = len(arr) left = [0] * n right = [0] * n stk = [] for i in range(n - 1, -1, -1): while stk and arr[stk[-1]] > arr[i]: stk.pop() right[i] = stk[-1] - i if stk else n - i stk.append(i) stk = [] for i in range(n): while stk and arr[stk[-1]] >= arr[i]: stk.pop() left[i] = i - stk[-1] if stk else i + 1 stk.append(i) res = 0 mod = int(1e9 + 7) for i in range(n): res = (res + arr[i] * left[i] * right[i]) % mod return res