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 10^9 + 7
.
For example:
arr = [3,1,2,4]
The subarrays are [3], [1], [2], [4], [3,1], [1,2], [2,4], [3,1,2], [1,2,4], [3,1,2,4]
.
The minimums are 3, 1, 2, 4, 1, 1, 2, 1, 1, 1
.
The sum is 17
.
Another example:
arr = [11,81,94,43,3]
Output: 444
Constraints:
1 <= arr.length <= 3 * 10^4
1 <= arr[i] <= 3 * 10^4
How would you approach this problem? Can you provide both a naive solution and an optimized solution, discussing their respective time and space complexities? Also, consider edge cases and explain how your solution handles them.
The most straightforward approach is to generate all possible subarrays and then find the minimum element in each subarray. After finding the minimum, sum them up and return the result modulo 10^9 + 7
.
def sum_of_minimums_brute_force(arr):
MOD = 10**9 + 7
total_sum = 0
n = len(arr)
for i in range(n):
for j in range(i, n):
sub_array = arr[i:j+1]
total_sum += min(sub_array)
total_sum %= MOD
return total_sum
To optimize, we can use a stack to find the number of subarrays in which each element is the minimum. For each element arr[i]
, we need to find the left and right boundaries such that arr[i]
is the minimum element in all subarrays within these boundaries.
arr[i]
, find the number of elements to its left and right that are greater than arr[i]
.arr[i]
is the minimum is (left + 1) * (right + 1)
.arr[i]
with the number of subarrays it is the minimum in, and add it to the total sum.10^9 + 7
at each step to avoid overflow.def sum_of_minimums_optimal(arr):
MOD = 10**9 + 7
n = len(arr)
stack = []
left = [0] * n
right = [0] * n
# Calculate left boundaries
for i in range(n):
while stack and arr[stack[-1]] > arr[i]:
stack.pop()
left[i] = i - stack[-1] if stack else i
stack.append(i)
stack = []
# Calculate right boundaries
for i in range(n - 1, -1, -1):
while stack and arr[stack[-1]] >= arr[i]:
stack.pop()
right[i] = stack[-1] - i if stack else n - i - 1
stack.append(i)
total_sum = 0
for i in range(n):
total_sum += arr[i] * (left[i] + 1) * (right[i] + 1)
total_sum %= MOD
return total_sum
left
and right
, of size n to store the left and right boundaries for each element.