Last Updated : 21 Feb, 2025
Try it on GfG Practice
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:
[Naive Approach] Generate all Subarrays - O(n²) Time and O(1) SpaceInput: 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.
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<int>& 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<int> 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 res
if __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.
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:
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<int>& 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<int> 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<Integer> 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 res
if __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<int> stk = new Stack<int>();
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.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4