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.
[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<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.
[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<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.
Similar Reads
Maximum subarray sum modulo m Given an array of n elements and an integer m. The task is to find the maximum value of the sum of its subarray modulo m i.e find the sum of each subarray mod m and print the maximum value of this modulo operation.Examples: Input: arr[] = {10, 7, 18}, m = 13Output: 12Explanation: All subarrays and t
7 min read
Size of The Subarray With Maximum Sum Given an array arr[] of size N, the task is to find the length of the subarray having maximum sum. Examples : Input : a[] = {1, -2, 1, 1, -2, 1} Output : Length of the subarray is 2 Explanation : Subarray with consecutive elements and maximum sum will be {1, 1}. So length is 2 Input : ar[] = { -2, -
10 min read
CSES Solutions - Maximum Subarray Sum Given an array arr[] of N integers, your task is to find the maximum sum of values in a contiguous, nonempty subarray. Examples: Input: N = 8, arr[] = {-1, 3, -2, 5, 3, -5, 2, 2}Output: 9Explanation: The subarray with maximum sum is {3, -2, 5, 3} with sum = 3 - 2 + 5 + 3 = 9. Input: N = 6, arr[] = {
5 min read
Maximum sum subarray of size range [L, R] Given an integer array arr[] of size N and two integer L and R. The task is to find the maximum sum subarray of size between L and R (both inclusive). Example: Input: arr[] = {1, 2, 2, 1}, L = 1, R = 3 Output: 5 Explanation: Subarray of size 1 are {1}, {2}, {2}, {1} and maximum sum subarray = 2 for
8 min read
Max sum of M non-overlapping subarrays of size K Given an array and two numbers M and K. We need to find the max sum of sums of M subarrays of size K (non-overlapping) in the array. (Order of array remains unchanged). K is the size of subarrays and M is the count of subarray. It may be assumed that size of array is more than m*k. If total array si
15+ min read
Print subarray with maximum sum Given an array arr[], the task is to print the subarray having maximum sum.Examples:Input: arr[] = {2, 3, -8, 7, -1, 2, 3}Output: 11Explanation: The subarray {7, -1, 2, 3} has the largest sum 11.Input: arr[] = {-2, -5, 6, -2, -3, 1, 5, -6}Output: {6, -2, -3, 1, 5}Explanation: The subarray {6, -2, -3
13 min read