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<sup>9</sup> + 7
.
For example:
arr = [3,1,2,4]
should return 17
because 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 of these subarrays are 3, 1, 2, 4, 1, 1, 2, 1, 1, 1
. The sum of the minimums is 3 + 1 + 2 + 4 + 1 + 1 + 2 + 1 + 1 + 1 = 17
.arr = [11,81,94,43,3]
should return 444
.What is the most efficient way to solve this problem? Consider the time and space complexity of your solution. Can you provide the code? What are the edge cases we should consider?
A naive approach would be to iterate through all possible subarrays, find the minimum element in each subarray, and sum up these minimums. This approach is straightforward but inefficient.
i
from 0 to n-1
.i
, iterate through all possible end indices j
from i
to n-1
.arr[i...j]
, find the minimum element.10^9 + 7
.def sum_of_minimums_brute_force(arr):
n = len(arr)
total_sum = 0
for i in range(n):
for j in range(i, n):
min_val = arr[i]
for k in range(i + 1, j + 1):
min_val = min(min_val, arr[k])
total_sum = (total_sum + min_val) % (10**9 + 7)
return total_sum
The time complexity of this brute-force approach is O(n^3), where n is the length of the input array. This is because we have three nested loops: the outer two loops to define the subarrays (O(n^2)), and the inner loop to find the minimum element in each subarray (O(n)).
The space complexity is O(1), as we only use a constant amount of extra space.
A more efficient approach involves using stacks to determine the left and right boundaries for each element in the array, where that element is the minimum.
arr[i]
, find the number of subarrays where arr[i]
is the minimum.left[i]
such that arr[i]
is the minimum to the left and right boundary right[i]
such that arr[i]
is the minimum to the right.left[i]
and right[i]
for each index i
.arr[i]
is the minimum is (i - left[i]) * (right[i] - i)
.arr[i] * (i - left[i]) * (right[i] - i)
for all i
, taking the modulo 10^9 + 7
.def sum_subarray_mins(arr):
n = len(arr)
left = [0] * n
right = [0] * n
stack = []
# Calculate left boundaries
for i in range(n):
while stack and arr[stack[-1]] > arr[i]:
stack.pop()
left[i] = stack[-1] if stack else -1
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] if stack else n
stack.append(i)
total_sum = 0
for i in range(n):
total_sum = (total_sum + arr[i] * (i - left[i]) * (right[i] - i)) % (10**9 + 7)
return total_sum
The time complexity of this optimized approach is O(n), where n is the length of the input array. This is because we iterate through the array three times: once to calculate the left boundaries, once to calculate the right boundaries, and once to compute the final sum. Each iteration is O(n), and stack operations are O(1) on average.
The space complexity is O(n), as we use two arrays, left
and right
, of size n to store the left and right boundaries for each element. We also use a stack, which, in the worst case, can contain all the elements of the array.