712193. Sum of subarray ranges
Medium
Sum of Subarray Ranges
Slug: sum-of-subarray-ranges
Difficulty: Medium
Id: 712193
Topic Tags: Arrays, Stack, Data Structures
Company Tags: None
Summary
Given an array arr and its range [l, r], find the sum of subarrays that fall within this range. This problem involves arrays and data structures, requiring a thoughtful algorithmic approach to solve efficiently.
Detailed Explanation
To tackle this challenge, we'll utilize two pointers technique along with a stack-based approach. The idea is to maintain a stack of ranges and their sums at any given moment.
Here's the step-by-step breakdown:
- Initialize an empty stack
st. - Iterate through the array from left to right:
- Calculate the sum of the current subarray (from the left boundary to the current index) and push it onto the stack along with its boundaries.
- Now, iterate through the array from right to left:
- For each element, calculate the sum of the current subarray (from the current index to the right boundary) and check if this range is within the given
[l, r]bounds. - If it is, add its sum to our result. We can do this efficiently by simply subtracting the previous left boundary from the current sum in the stack.
- For each element, calculate the sum of the current subarray (from the current index to the right boundary) and check if this range is within the given
- Return the final result, which represents the sum of all subarrays that fall within the range
[l, r].
Here's a visual representation:
+---------------+
| arr |
+---------------+
l r
+---------------+
| [0..3] 10 |
| [4..6] 20 |
| [7..9] 30 |
+---------------+
In this example, the sum of subarrays within [l, r] would be:
arr[0..3]: 10arr[4..6]: 40 (20 + 20)arr[7..9]: 30
The final result is: 10 + 40 + 30 = 80.
Time complexity: O(n), where n is the size of the array. Space complexity: O(1) due to the constant space needed for the stack and variables.
Optimized Solutions
Java
public int sumOfSubarrayRanges(int[] arr, int l, int r) {
Stack<int[]> st = new Stack<>();
int currSum = 0;
for (int i = 0; i < arr.length; i++) {
currSum += arr[i];
if (i >= l && i <= r) {
while (!st.isEmpty() && st.peek()[1] < l) {
currSum -= st.pop()[0];
}
}
if (i >= r) continue;
st.push(new int[]{currSum, i});
}
int res = 0;
while (!st.isEmpty()) {
int[] top = st.pop();
int left = top[1] - l + 1;
res += top[0] * left;
}
return res;
}