Problem
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
.
Examples
Example 1:
|
|
Example 2:
|
|
Solution
Method 1 - Monotonic Increasing Stack
How Can Monotonic Stack Be Applied to This Problem?
Consider the element 3
in the array:
|
|
The nearest smaller elements to the left (NSL) and right (NSR) (OR previous less element (PLE) and next less element(NLE)) of 3
are 2
and 1
, respectively. The distance between 3
and its NSL 2
is 4, and the distance between 3
and its NSR 1
is 3.
The distance between 3
and its NSL 2
is 4
. The distance between 3
and its NSR 1
is 3.
How Many Subarrays with 3 Being Its Minimum Value?
The answer is 4*3
.
|
|
How Much the Element 3 Contributes to the Final Answer?
It is 3*(4*3)
.
Algorithm
- Denote by
left[i]
the distance between elementA[i]
and its NSL. - Denote by
right[i]
the distance between elementA[i]
and its NSR. - The final answer is,
sum(arr[i]*left[i]*right[i] )
Here is the detailed approach:
- Monotonic Stack with Contribution Calculation:
- Use a monotonic stack to track previous and next smaller elements for each element.
- Compute how many subarrays in which each element is the minimum element.
- Maintain two arrays,
left
andright
, whereleft[i]
indicates the number of contiguous subarrays ending atarr[i]
in whicharr[i]
is the minimum, andright[i]
indicates the number of contiguous subarrays starting atarr[i]
in whicharr[i]
is the minimum. - The product of
left[i]
andright[i]
gives the count of contexts wherearr[i]
is the minimum.
- Sum Calculation:
- Calculate the sum of the contributions of all elements being the minimum in their respective subarrays and take modulo
10^9 + 7
to handle large numbers.
- Calculate the sum of the contributions of all elements being the minimum in their respective subarrays and take modulo
We have already seen following problems:
- NSL - Nearest Smallest Element to Left of Every Element
- NSR - Nearest Smaller Element to Right of every element
We also used it in Largest Rectangle in Histogram.
Code
|
|
|
|
Complexity
- ⏰ Time complexity:
O(n)
for traversing the entire array and handling stack operations. - 🧺 Space complexity:
O(n)
for storing left, right, and the stack.
Method 2 - DP and Monotonic Stack
Using a monotonic increasing stack to store indices:
dp[i + 1]
: Stores the sum of minimums of all subarrays ending witharr[i]
dp[i + 1] = dp[prev + 1] + (i - prev) * arr[i]
, whereprev
is the index of the previous smaller element, and as we are using monotonous increasing stackstack.peek()
For eg. for arr = [3, 1, 2, 4, 3]
, when i = 4
, all subarrays end with arr[4]
(which is 3):
[3]
[4, 3]
[2, 4, 3]
[1, 2, 4, 3]
[3, 1, 2, 4, 3]
Here, stack.peek() = 2
and arr[2] = 2
.
For the first two subarrays [3]
and [4, 3]
, the sum of minimum is (i - stack.peek()) * arr[i] = 6
.
For the last three subarrays [2, 4, 3]
, [1, 2, 4, 3]
, [3, 1, 2, 4, 3]
, as they all contain a 2
which is less than 3
, the sum of minimum is dp[stack.peek() + 1] = 4
.
Thus, dp[i + 1] = 4 + 6 = 10
.
Code
|
|
|
|
Complexity
- ⏰ Time complexity:
O(n)
for iterating through the array and handling stack operations. - 🧺 Space complexity:
O(n)
for storing the dp array and stack.