907-sum-of-subarray-minimums¶
Try it on leetcode
Description¶
Given an array of integers arr, find the sum of min(b)
, where b
ranges over every (contiguous) subarray of arr
. Since the answer may be large, return the answer modulo 109 + 7
.
Example 1:
Input: arr = [3,1,2,4] Output: 17 Explanation: Subarrays are [3], [1], [2], [4], [3,1], [1,2], [2,4], [3,1,2], [1,2,4], [3,1,2,4]. Minimums are 3, 1, 2, 4, 1, 1, 2, 1, 1, 1. Sum is 17.
Example 2:
Input: arr = [11,81,94,43,3] Output: 444
Constraints:
1 <= arr.length <= 3 * 104
1 <= arr[i] <= 3 * 104
Solution(Python)¶
class Solution:
def __init__(self):
self.mod = (10**9) + 7
def sumSubarrayMins(self, arr: List[int]) -> int:
return self.dp(arr)
# Time Complexity: O(n^3)
# Space Complexity: O(1)
def bruteforce(self, arr: List[int]) -> int:
n = len(arr)
res = 0
for end in range(n):
for start in range(n):
min_ = float("-inf")
for i in range(start, end + 1):
min_ = min(min_, arr[i])
res += min_ & self.mod
return res
# Time Complexity: O(n^2)
# Space Complexity: O(1)
def betterbruteforce(self, arr: List[int]) -> int:
n = len(arr)
res = 0
for start in range(n):
min_ = arr[start]
for i in range(start, n):
min_ = min(min_, arr[i])
res += min_ % self.mod
return res
# Time Complexity: O(n)
# Space Complexity: O(n)
def monotonicstack(self, arr: List[int]) -> int:
n = len(arr)
s1 = []
s2 = []
left = [None] * n
right = [None] * n
for i in range(n):
cnt = 1
while len(s1) > 0 and s1[-1][0] > arr[i]:
cnt += s1[-1][1]
s1.pop()
s1.append([arr[i], cnt])
left[i] = cnt
for i in range(n - 1, -1, -1):
cnt = 1
while len(s2) > 0 and s2[-1][0] >= arr[i]:
cnt += s2[-1][1]
s2.pop()
s2.append([arr[i], cnt])
right[i] = cnt
res = 0
for i in range(n):
res += (left[i] * right[i] * arr[i]) % self.mod
return res % self.mod
# Time Complexity: O(n)
# Space Complexity: O(n)
def dp(self, arr: List[int]) -> int:
n = len(arr)
dp = [0] * n
st = []
ans = 0
for i in range(n - 1, -1, -1):
while st and arr[st[-1]] >= arr[i]:
st.pop()
if st:
dp[i] = dp[st[-1]] + arr[i] * (st[-1] - i)
else:
dp[i] = arr[i] * (n - i)
st.append(i)
ans += dp[i] % self.mod
return ans % self.mod