Given an array arr[], the task is to find the maximum sum of lengths of all non-overlapping subarrays with k as the maximum element in the subarray.
Examples:
Input: arr[] = [2, 1, 4, 9, 2, 3, 8, 3, 4], k = 4
Output: 5
Explanation: The non-overlapping subarrays whose maximum element is 4 are:
[2, 1, 4] -> Length = 3,
[3, 4] -> Length = 2,
Therefore, the total length is 3 + 2 = 5.
Input: arr[] = [1, 2, 3, 2, 3, 4, 1], k = 4
Output: 7
Explanation: The entire array [1, 2, 3, 2, 3, 4, 1] has maximum element equal to 4. Hence, the total length is 7.
Table of Content
[Naive Approach] Check Every Subarray - O(2^n) Time O(n) Space
The idea is to try every possible subarray starting from the current index. If a subarray has maximum element equal to
k, we can either take it and continue from the next non-overlapping position or skip the current index. The maximum of all such choices gives the answer.
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
int solve(int idx, vector<int> &arr, int k)
{
int n = arr.size();
if (idx >= n)
return 0;
// Option 1: Skip current index
int res = solve(idx + 1, arr, k);
int mx = INT_MIN;
// Try every subarray starting from idx
for (int j = idx; j < n; j++)
{
mx = max(mx, arr[j]);
if (mx == k)
{
res = max(res, (j - idx + 1) + solve(j + 1, arr, k));
}
}
return res;
}
int calculateMaxSumLength(vector<int> &arr, int k)
{
return solve(0, arr, k);
}
// Driver Code
int main()
{
vector<int> arr = {1, 2, 3, 2, 3, 4, 1};
int k = 4;
cout << calculateMaxSumLength(arr, k);
return 0;
}
import java.util.*;
public class GfG {
public static int solve(int idx, int[] arr, int k) {
int n = arr.length;
if (idx >= n)
return 0;
int res = solve(idx + 1, arr, k);
int mx = Integer.MIN_VALUE;
for (int j = idx; j < n; j++) {
mx = Math.max(mx, arr[j]);
if (mx == k) {
res = Math.max(res, (j - idx + 1) + solve(j + 1, arr, k));
}
}
return res;
}
public int calculateMaxSumLength(int[] arr, int k) {
return solve(0, arr, k);
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 2, 3, 4, 1};
int k = 4;
GfG ob = new GfG();
System.out.println(ob.calculateMaxSumLength(arr, k));
}
}
def solve(idx, arr, k):
n = len(arr)
if idx >= n:
return 0
# Option 1: Skip current index
res = solve(idx + 1, arr, k)
mx = float('-inf')
# Try every subarray starting from idx
for j in range(idx, n):
mx = max(mx, arr[j])
if mx == k:
res = max(res, (j - idx + 1) + solve(j + 1, arr, k))
return res
def calculateMaxSumLength(arr, k):
return solve(0, arr, k)
# Driver Code
if __name__ == "__main__":
arr = [1, 2, 3, 2, 3, 4, 1]
k = 4
print(calculateMaxSumLength(arr, k))
using System;
class GfG {
static int solve(int idx, int[] arr, int k)
{
int n = arr.Length;
if (idx >= n)
return 0;
// Option 1: Skip current index
int res = solve(idx + 1, arr, k);
int mx = int.MinValue;
// Try every subarray starting from idx
for (int j = idx; j < n; j++) {
mx = Math.Max(mx, arr[j]);
if (mx == k) {
res = Math.Max(res,
(j - idx + 1)
+ solve(j + 1, arr, k));
}
}
return res;
}
static int calculateMaxSumLength(int[] arr, int k)
{
return solve(0, arr, k);
}
static void Main()
{
int[] arr = { 1, 2, 3, 2, 3, 4, 1 };
int k = 4;
Console.WriteLine(calculateMaxSumLength(arr, k));
}
}
function solve(idx, arr, k)
{
const n = arr.length;
if (idx >= n)
return 0;
// Option 1: Skip current index
let res = solve(idx + 1, arr, k);
let mx = -Infinity;
// Try every subarray starting from idx
for (let j = idx; j < n; j++) {
mx = Math.max(mx, arr[j]);
if (mx === k) {
res = Math.max(res, (j - idx + 1)
+ solve(j + 1, arr, k));
}
}
return res;
}
function calculateMaxSumLength(arr, k)
{
return solve(0, arr, k);
}
// Driver Code
const arr = [ 1, 2, 3, 2, 3, 4, 1 ];
const k = 4;
console.log(calculateMaxSumLength(arr, k));
Output
7
Time Complexity: O(2^n)
Auxiliary Space: O(n)
[Expected Approach] Split by Elements Greater than k - O(n) Time O(1) Space
The idea is to split the array into contiguous segments containing only elements less than or equal to
k. Elements greater thankact as separators since they cannot be part of a subarray whose maximum element isk. For each segment, if it contains at least one occurrence ofk, add its length to the answer. The sum of lengths of all such segments gives the required result.
#include <iostream>
using namespace std;
// Function to calculate the maximum sum of consecutive elements less than or equal
// to k
int calculateMaxSumLength(vector<int> &arr, int k)
{
int n = arr.size();
int res = 0;
// Variable to store the count of consecutive elements less than
// or equal to k
int count = 0;
// Flag to check if k is present in the consecutive elements
int flag = 0;
for (int i = 0; i < n;)
{
count = 0;
flag = 0;
while (i < n && arr[i] <= k)
{
count++;
if (arr[i] == k)
flag = 1;
i++;
}
if (flag == 1)
// Adding the count of consecutive elements containing k
res += count;
while (i < n && arr[i] > k)
// Skipping consecutive elements greater than k
i++;
}
return res;
}
// Driver Code
int main()
{
vector<int> arr = {1, 2, 3, 2, 3, 4, 1};
int k = 4;
cout << calculateMaxSumLength(arr, k);
return 0;
}
import java.util.Arrays;
public class GfG {
// Function to calculate the maximum sum of consecutive
// elements less than or equal to k
public int calculateMaxSumLength(int[] arr, int k) {
int n = arr.length;
int ans = 0;
int count = 0;
int flag = 0;
for (int i = 0; i < n;) {
count = 0;
flag = 0;
while (i < n && arr[i] <= k) {
count++;
if (arr[i] == k)
flag = 1;
i++;
}
if (flag == 1)
ans += count;
while (i < n && arr[i] > k)
i++;
}
return ans;
}
// Driver Code
public static void main(String[] args) {
int[] arr = {1, 2, 3, 2, 3, 4, 1};
int k = 4;
GfG ob = new GfG();
System.out.println(ob.calculateMaxSumLength(arr, k));
}
}
def calculateMaxSumLength(arr, k):
n = len(arr)
res = 0
# Variable to store the count of consecutive elements less than
# or equal to k
count = 0
# Flag to check if k is present in the consecutive elements
flag = 0
i = 0
while i < n:
count = 0
flag = 0
while i < n and arr[i] <= k:
count += 1
if arr[i] == k:
flag = 1
i += 1
if flag == 1:
# Adding the count of consecutive elements containing k
res += count
while i < n and arr[i] > k:
# Skipping consecutive elements greater than k
i += 1
return res
# Driver Code
if __name__ == "__main__":
arr = [1, 2, 3, 2, 3, 4, 1]
k = 4
print(calculateMaxSumLength(arr, k))
using System;
// Function to calculate the maximum sum of consecutive
// elements less than or equal to k
public class GfG {
public static int calculateMaxSumLength(int[] arr,
int k)
{
int n = arr.Length;
int res = 0;
// Variable to store the count of consecutive
// elements less than or equal to k
int count = 0;
// Flag to check if k is present in the consecutive
// elements
int flag = 0;
for (int i = 0; i < n;) {
count = 0;
flag = 0;
while (i < n && arr[i] <= k) {
count++;
if (arr[i] == k)
flag = 1;
i++;
}
if (flag == 1)
// Adding the count of consecutive elements
// containing k
res += count;
while (i < n && arr[i] > k)
// Skipping consecutive elements greater
// than k
i++;
}
return res;
}
// Driver Code
public static void Main()
{
int[] arr = { 1, 2, 3, 2, 3, 4, 1 };
int k = 4;
Console.WriteLine(calculateMaxSumLength(arr, k));
}
}
function calculateMaxSumLength(arr, k)
{
let n = arr.length;
let res = 0;
// Variable to store the count of consecutive elements
// less than or equal to k
let count = 0;
// Flag to check if k is present in the consecutive
// elements
let flag = 0;
for (let i = 0; i < n;) {
count = 0;
flag = 0;
while (i < n && arr[i] <= k) {
count++;
if (arr[i] === k)
flag = 1;
i++;
}
if (flag === 1)
// Adding the count of consecutive elements
// containing k
res += count;
while (i < n && arr[i] > k)
// Skipping consecutive elements greater than k
i++;
}
return res;
}
// Driver Code
let arr = [ 1, 2, 3, 2, 3, 4, 1 ];
let k = 4;
console.log(calculateMaxSumLength(arr, k));
Output
7
Time Complexity: O(n)
Auxiliary Space: O(1)