Sum of Max of Subarrays (original) (raw)
Last Updated : 21 Feb, 2025
Given an array **arr[], the task is to find the sum of the maximum **elements of every possible non-empty sub-arrays of the given array **arr[].
**Examples:
**Input: arr[] = [1, 3, 2]
**Output: 15
**Explanation: All possible non-empty subarrays of [1, 3, 2] are {1}, {3}, {2}, {1, 3}, {3, 2} and {1, 3, 2}. The maximum elements of the subarrays are 1, 3, 2, 3, 3, 3 respectively. The sum will be 15.**Input: arr[] = [3, 1]
**Output: 7
**Explanation: All possible non-empty subarrays of [3, 1] are {3}, {1} and {3, 1}. The maximum elements of the subarrays are 3, 1, 3 respectively. The sum will be 7.**Input: arr[] = [8, 0, 1]
**Output: 26
**Explanation: All possible non-empty subarrays of [8, 0, 1] are {8}, {0}, {1}, {8, 0}, {0, 1} and {8, 0, 1}. The maximum elements of the subarrays are 8, 0, 1, 8, 1, 8 respectively. The sum will be 26.
Table of Content
- [Brute Force Approach] Generate all Subarrays - O(n²) Time and O(1) Space
- [Expected Approach] Using Monotonic Stack - O(n) Time and O(n) Space
[Naive Approach] Generate all Subarrays - O(**n²) Time and O(1) Space
The **idea is to compute the **sum of the **maximum elements of **all possible subarrays of the given array. To do this, we **generate all subarrays, find their **maximum element, and **sum up these **maximum values.
Below is the implementation of the above approach:
C++ `
// C++ implementation to find sum of max // of subarrays by generating all subarrays #include <bits/stdc++.h> using namespace std;
int sumOfMax(vector& arr) { int n = arr.size(); int res = 0;
// Pick starting point of subarray
for (int i = 0; i < n; ++i) {
int currMax = arr[i];
// Pick ending point
for (int j = i; j < n; ++j) {
// Max of subarray from i to j
currMax = max(currMax, arr[j]);
res += currMax;
}
}
return res;}
int main() { vector arr = {1, 3, 2}; cout << sumOfMax(arr) << endl; return 0; }
C
// C implementation to find sum of max // of subarrays by generating all subarrays #include <stdio.h>
int sumOfMax(int arr[], int n) { int res = 0;
// Pick starting point of subarray
for (int i = 0; i < n; ++i) {
int currMax = arr[i];
// Pick ending point
for (int j = i; j < n; ++j) {
// Max of subarray from i to j
if (arr[j] > currMax) {
currMax = arr[j];
}
res += currMax;
}
}
return res;}
int main() { int arr[] = {1, 3, 2}; int n = sizeof(arr) / sizeof(arr[0]);
printf("%d\n", sumOfMax(arr, n));
return 0;}
Java
// Java implementation to find sum of max // of subarrays by generating all subarrays import java.util.*;
class GfG {
static int sumOfMax(int[] arr) {
int n = arr.length;
int res = 0;
// Pick starting point of subarray
for (int i = 0; i < n; ++i) {
int currMax = arr[i];
// Pick ending point
for (int j = i; j < n; ++j) {
// Max of subarray from i to j
currMax = Math.max(currMax, arr[j]);
res += currMax;
}
}
return res;
}
public static void main(String[] args) {
int[] arr = {1, 3, 2};
System.out.println(sumOfMax(arr));
}}
Python
Python implementation to find sum of max
of subarrays by generating all subarrays
def sumOfMax(arr): n = len(arr) res = 0
# Pick starting point of subarray
for i in range(n):
currMax = arr[i]
# Pick ending point
for j in range(i, n):
# Max of subarray from i to j
currMax = max(currMax, arr[j])
res += currMax
return resif name == "main": arr = [1, 3, 2] print(sumOfMax(arr))
C#
// C# implementation to find sum of max // of subarrays by generating all subarrays using System;
class GfG {
static int sumOfMax(int[] arr) {
int n = arr.Length;
int res = 0;
// Pick starting point of subarray
for (int i = 0; i < n; ++i) {
int currMax = arr[i];
// Pick ending point
for (int j = i; j < n; ++j) {
// Max of subarray from i to j
currMax = Math.Max(currMax, arr[j]);
res += currMax;
}
}
return res;
}
static void Main() {
int[] arr = {1, 3, 2};
Console.WriteLine(sumOfMax(arr));
}}
JavaScript
// Javascript implementation to find sum of max // of subarrays by generating all subarrays function sumOfMax(arr) { let n = arr.length; let res = 0;
// Pick starting point of subarray
for (let i = 0; i < n; i++) {
let currMax = arr[i];
// Pick ending point
for (let j = i; j < n; j++) {
// Max of subarray from i to j
currMax = Math.max(currMax, arr[j]);
res += currMax;
}
}
return res;}
// Driver Code let arr = [1, 3, 2]; console.log(sumOfMax(arr));
`
**Time Complexity: O(n²) due to the nested loops iterating over all subarrays.
**Space Complexity: O(1) as no extra space is used apart from variables.
[Expected Approach] Using Monotonic Stack - O(n) Time and O(n) Space
The idea is to efficiently compute the sum of the maximum elements of all subarrays using a **monotonic stack approach instead of brute force. Instead of generating all subarrays explicitly, we determine how many subarrays each element contributes as the **maximum value.
To achieve this, we find for each element the number of subarrays where it remains the maximum by computing its **left boundary (how many contiguous elements to the left it dominates) and **right boundary (how many contiguous elements to the right it dominates). This is done using a **monotonic stack, which efficiently finds the nearest greater elements to the left and right in **O(n) time.
The contribution of each element to the total sum is then given by multiplying its value with the number of subarrays in which it is the maximum ****(**
left[i] * right[i]), ensuring an optimal and direct computation of the result without generating all subarrays explicitly.
Steps to implement the above idea:
- Initialize **stk, left, and right arrays to store **boundaries.
- Iterate **left to right, using a **monotonic stack to find the **left boundary for each element.
- Clear the stack and iterate **right to left to compute the **right boundary.
- Compute each element's contribution by multiplying its value with **left[i] * right[i].
- **Sum up all contributions to get the **final result.
- Return the computed sum.
Below is the implementation of the above approach:
C++ `
// C++ implementation to find sum of max // of subarrays using Monotonic Stack #include <bits/stdc++.h> using namespace std;
int sumOfMax(vector& arr) {
int n = arr.size();
int res = 0;
stack<int> stk;
vector<int> left(n), right(n);
// Finding the left boundary for each element
for (int i = 0; i < n; ++i) {
// Pop elements smaller than arr[i] from stack
while (!stk.empty() && arr[stk.top()] < arr[i]) {
stk.pop();
}
// Calculate left boundary count
left[i] = (stk.empty()) ? (i + 1) : (i - stk.top());
// Push current index into stack
stk.push(i);
}
// Clear the stack for right boundary computation
while (!stk.empty()) {
stk.pop();
}
// Finding the right boundary for each element
for (int i = n - 1; i >= 0; --i) {
// Pop elements smaller or equal to arr[i] from stack
while (!stk.empty() && arr[stk.top()] <= arr[i]) {
stk.pop();
}
// Calculate right boundary count
right[i] = (stk.empty()) ? (n - i) : (stk.top() - i);
// Push current index into stack
stk.push(i);
}
// Compute sum of max elements of all subarrays
for (int i = 0; i < n; ++i) {
// Contribution of arr[i] as max in subarrays
res += arr[i] * left[i] * right[i];
}
return res;}
int main() { vector arr = {1, 3, 2};
// Print the sum of maximum elements in all subarrays
cout << sumOfMax(arr) << endl;
return 0;}
Java
// Java implementation to find sum of max // of subarrays using Monotonic Stack import java.util.*;
class GfG { static int sumOfMax(int[] arr) { int n = arr.length; int res = 0; Stack stk = new Stack<>(); int[] left = new int[n], right = new int[n];
// Finding the left boundary for each element
for (int i = 0; i < n; ++i) {
// Pop elements smaller than arr[i] from stack
while (!stk.isEmpty() && arr[stk.peek()] < arr[i]) {
stk.pop();
}
// Calculate left boundary count
left[i] = (stk.isEmpty()) ? (i + 1) : (i - stk.peek());
// Push current index into stack
stk.push(i);
}
// Clear the stack for right boundary computation
stk.clear();
// Finding the right boundary for each element
for (int i = n - 1; i >= 0; --i) {
// Pop elements smaller or equal to arr[i] from stack
while (!stk.isEmpty() && arr[stk.peek()] <= arr[i]) {
stk.pop();
}
// Calculate right boundary count
right[i] = (stk.isEmpty()) ? (n - i) : (stk.peek() - i);
// Push current index into stack
stk.push(i);
}
// Compute sum of max elements of all subarrays
for (int i = 0; i < n; ++i) {
// Contribution of arr[i] as max in subarrays
res += arr[i] * left[i] * right[i];
}
return res;
}
public static void main(String[] args) {
int[] arr = {1, 3, 2};
System.out.println(sumOfMax(arr));
}}
Python
Python implementation to find sum of max
of subarrays using Monotonic Stack
def sumOfMax(arr): n = len(arr) res = 0 stk = [] left = [0] * n right = [0] * n
# Finding the left boundary for each element
for i in range(n):
# Pop elements smaller than arr[i] from stack
while stk and arr[stk[-1]] < arr[i]:
stk.pop()
# Calculate left boundary count
left[i] = (i + 1) if not stk else (i - stk[-1])
# Push current index into stack
stk.append(i)
# Clear the stack for right boundary computation
stk.clear()
# Finding the right boundary for each element
for i in range(n - 1, -1, -1):
# Pop elements smaller or equal to arr[i] from stack
while stk and arr[stk[-1]] <= arr[i]:
stk.pop()
# Calculate right boundary count
right[i] = (n - i) if not stk else (stk[-1] - i)
# Push current index into stack
stk.append(i)
# Compute sum of max elements of all subarrays
for i in range(n):
# Contribution of arr[i] as max in subarrays
res += arr[i] * left[i] * right[i]
return resif name == "main": arr = [1, 3, 2]
# Print the sum of maximum elements in all subarrays
print(sumOfMax(arr))C#
// C# implementation to find sum of max // of subarrays using Monotonic Stack using System; using System.Collections.Generic;
class GfG { static int sumOfMax(int[] arr) { int n = arr.Length; int res = 0; Stack stk = new Stack(); int[] left = new int[n], right = new int[n];
// Finding the left boundary for each element
for (int i = 0; i < n; ++i) {
// Pop elements smaller than arr[i] from stack
while (stk.Count > 0 && arr[stk.Peek()] < arr[i]) {
stk.Pop();
}
// Calculate left boundary count
left[i] = (stk.Count == 0) ? (i + 1) : (i - stk.Peek());
// Push current index into stack
stk.Push(i);
}
// Clear the stack for right boundary computation
stk.Clear();
// Finding the right boundary for each element
for (int i = n - 1; i >= 0; --i) {
// Pop elements smaller or equal to arr[i] from stack
while (stk.Count > 0 && arr[stk.Peek()] <= arr[i]) {
stk.Pop();
}
// Calculate right boundary count
right[i] = (stk.Count == 0) ? (n - i) : (stk.Peek() - i);
// Push current index into stack
stk.Push(i);
}
// Compute sum of max elements of all subarrays
for (int i = 0; i < n; ++i) {
// Contribution of arr[i] as max in subarrays
res += arr[i] * left[i] * right[i];
}
return res;
}
static void Main() {
int[] arr = {1, 3, 2};
Console.WriteLine(sumOfMax(arr));
}}
JavaScript
// JavaScript implementation to find sum of max // of subarrays using Monotonic Stack
function sumOfMax(arr) { let n = arr.length; let res = 0; let stk = []; let left = new Array(n).fill(0); let right = new Array(n).fill(0);
// Finding the left boundary for each element
for (let i = 0; i < n; ++i) {
// Pop elements smaller than arr[i] from stack
while (stk.length > 0 && arr[stk[stk.length - 1]] < arr[i]) {
stk.pop();
}
// Calculate left boundary count
left[i] = (stk.length === 0) ? (i + 1) : (i - stk[stk.length - 1]);
// Push current index into stack
stk.push(i);
}
// Clear the stack for right boundary computation
stk = [];
// Finding the right boundary for each element
for (let i = n - 1; i >= 0; --i) {
// Pop elements smaller or equal to arr[i] from stack
while (stk.length > 0 && arr[stk[stk.length - 1]] <= arr[i]) {
stk.pop();
}
// Calculate right boundary count
right[i] = (stk.length === 0) ? (n - i) : (stk[stk.length - 1] - i);
// Push current index into stack
stk.push(i);
}
// Compute sum of max elements of all subarrays
for (let i = 0; i < n; ++i) {
// Contribution of arr[i] as max in subarrays
res += arr[i] * left[i] * right[i];
}
return res;}
// Driver Code let arr = [1, 3, 2]; console.log(sumOfMax(arr));
`
**Time Complexity: O(n) since each element is processed at most twice using monotonic stacks.
**Space Complexity: O(n)due to the left, right, and stk arrays.