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 subarray {2}.
Subarray of size 2 are {1, 2}, {2, 2}, {2, 1}, and maximum sum subarray = 4 for subarray {2, 2}.
Subarray of size 3 are {1, 2, 2}, {2, 2, 1}, and maximum sum subarray = 5 for subarray {2, 2, 1}.
Hence the maximum possible sum subarray is 5.Input: arr[] = {-1, -3, -7, -11}, L = 1, R = 4
Output: -1
Approach:
- Here we will use the concept of sliding window which is discuss in this post.
- First calculate prefix sum of array in array pre[].
- Next iterate over the range L to N -1, and consider all subarray of size L to R.
- Create a multiset for storing prefix sums of subarray length L to R.
- Now to find maximum sum subarray ending at index i just subtract pre[i] and minimum of all values from pre[i – L] to pre[i – R].
- Finally return maximum of all sums.
Below is the implementation of the above approach:
// C++ program to find Maximum sum // subarray of size between L and R. #include <bits/stdc++.h> using namespace std;
// function to find Maximum sum subarray // of size between L and R void max_sum_subarray(vector< int > arr,
int L, int R)
{ int n = arr.size();
int pre[n] = { 0 };
// calculating prefix sum
pre[0] = arr[0];
for ( int i = 1; i < n; i++) {
pre[i] = pre[i - 1] + arr[i];
}
multiset< int > s1;
// maintain 0 for initial
// values of i upto R
// Once i = R, then
// we need to erase that 0 from
// our multiset as our first
// index of subarray
// cannot be 0 anymore.
s1.insert(0);
int ans = INT_MIN;
ans = max(ans, pre[L - 1]);
// we maintain flag to
// counter if that initial
// 0 was erased from set or not.
int flag = 0;
for ( int i = L; i < n; i++) {
// erase 0 from multiset once i=b
if (i - R >= 0) {
if (flag == 0) {
auto it = s1.find(0);
s1.erase(it);
flag = 1;
}
}
// insert pre[i-L]
if (i - L >= 0)
s1.insert(pre[i - L]);
// find minimum value in multiset.
ans = max(ans,
pre[i] - *s1.begin());
// erase pre[i-R]
if (i - R >= 0) {
auto it = s1.find(pre[i - R]);
s1.erase(it);
}
}
cout << ans << endl;
} // Driver code int main()
{ int L, R;
L = 1;
R = 3;
vector< int > arr = { 1, 2, 2, 1 };
max_sum_subarray(arr, L, R);
return 0;
} |
// Java program to find Maximum sum // subarray of size between L and R. import java.util.*;
class GFG {
// function to find Maximum sum subarray // of size between L and R static void max_sum_subarray(List<Integer> arr, int L, int R){
int n = arr.size();
int [] pre = new int [n + 1 ];
// calculating prefix sum
// here pre[0] = 0
for ( int i = 1 ; i <= n; i++) {
pre[i] = pre[i - 1 ]+arr.get(i - 1 );
}
// treemap for storing prefix sums for
// subarray length L to R
TreeMap<Integer, Integer> s1 = new TreeMap<>();
int ans = Integer.MIN_VALUE;
for ( int i = L; i <= n; i++) {
// if i > R, erase pre[i - R - 1]
// note that pre[0] = 0
if (i > R) {
// decrement count of pre[i - R - 1]
s1.put(pre[i - R - 1 ], s1.get(pre[i - R - 1 ])- 1 );
// if count is zero, element is not present
// in map so remove it
if (s1.get(pre[i - R - 1 ]) == 0 )
s1.remove(pre[i - R - 1 ]);
}
// insert pre[i - L]
s1.put(pre[i - L], s1.getOrDefault(pre[i - L], 0 )+ 1 );
// find minimum value in treemap.
ans = Math.max(ans, pre[i] - s1.firstKey());
}
System.out.println(ans);
} // Driver code public static void main(String[] args){
int L, R;
L = 1 ;
R = 3 ;
List<Integer> arr = Arrays.asList( 1 , 2 , 2 , 1 );
max_sum_subarray(arr, L, R);
}
} // This code is contributed by Utkarsh Sharma |
// C# program to find Maximum sum // subarray of size between L and R. using System;
using System.Collections.Generic;
class GFG
{ // function to find Maximum sum subarray
// of size between L and R
static void max_sum_subarray(List< int > arr, int L, int R)
{
int n = arr.Count;
int [] pre = new int [n];
// calculating prefix sum
pre[0] = arr[0];
for ( int i = 1; i < n; i++)
{
pre[i] = pre[i - 1] + arr[i];
}
List< int > s1 = new List< int >();
// maintain 0 for initial
// values of i upto R
// Once i = R, then
// we need to erase that 0 from
// our multiset as our first
// index of subarray
// cannot be 0 anymore.
s1.Add(0);
int ans = Int32.MinValue;
ans = Math.Max(ans, pre[L - 1]);
// we maintain flag to
// counter if that initial
// 0 was erased from set or not.
int flag = 0;
for ( int i = L; i < n; i++)
{
// erase 0 from multiset once i=b
if (i - R >= 0)
{
if (flag == 0)
{
int it = s1.IndexOf(0);
s1.RemoveAt(it);
flag = 1;
}
}
// insert pre[i-L]
if (i - L >= 0)
s1.Add(pre[i - L]);
// find minimum value in multiset.
ans = Math.Max(ans, pre[i] - s1[0]);
// erase pre[i-R]
if (i - R >= 0)
{
int it = s1.IndexOf(pre[i - R]);
s1.RemoveAt(it);
}
}
Console.WriteLine(ans);
}
// Driver code
static void Main()
{
int L, R;
L = 1;
R = 3;
List< int > arr = new List< int >(){1, 2, 2, 1};
max_sum_subarray(arr, L, R);
}
} // This code is contributed by divyesh072019 |
// Javascript program to find Maximum sum // subarray of size between L and R. // function to find Maximum sum subarray // of size between L and R
function max_sum_subarray(arr,L,R)
{ let n = arr.length;
let pre = new Array(n);
// calculating prefix sum
pre[0] = arr[0];
for (let i = 1; i < n; i++)
{
pre[i] = pre[i - 1] + arr[i];
}
let s1 = []
// maintain 0 for initial
// values of i upto R
// Once i = R, then
// we need to erase that 0 from
// our multiset as our first
// index of subarray
// cannot be 0 anymore.
s1.push(0);
let ans = Number.MIN_VALUE;
ans = Math.max(ans, pre[L - 1]);
// we maintain flag to
// counter if that initial
// 0 was erased from set or not.
let flag = 0;
for (let i = L; i < n; i++)
{
// erase 0 from multiset once i=b
if (i - R >= 0)
{
if (flag == 0)
{
let it = s1.indexOf(0);
s1.splice(it,1);
flag = 1;
}
}
// insert pre[i-L]
if (i - L >= 0)
s1.push(pre[i - L]);
// find minimum value in multiset.
ans = Math.max(ans, pre[i] - s1[0]);
// erase pre[i-R]
if (i - R >= 0)
{
let it = s1.indexOf(pre[i - R]);
s1.splice(it,1);
}
}
document.write(ans);
} // Driver code let L, R; L = 1; R = 3; let arr = [1, 2, 2, 1]; max_sum_subarray(arr, L, R); // This code is contributed by avanitrachhadiya2155 |
def max_sum_subarray(arr, L, R):
n = len (arr)
pre = [ 0 ] * n
# calculating prefix sum
pre[ 0 ] = arr[ 0 ]
for i in range ( 1 , n):
pre[i] = pre[i - 1 ] + arr[i]
s1 = set ()
# maintain 0 for initial
# values of i up to R
# Once i = R, then
# we need to erase that 0 from
# our set as our first
# index of subarray
# cannot be 0 anymore.
s1.add( 0 )
ans = float ( '-inf' )
ans = max (ans, pre[L - 1 ])
# we maintain flag to
# counter if that initial
# 0 was erased from set or not.
flag = 0
for i in range (L, n):
# erase 0 from set once i=b
if i - R > = 0 :
if flag = = 0 :
s1.remove( 0 )
flag = 1
# insert pre[i-L]
if i - L > = 0 :
s1.add(pre[i - L])
# find minimum value in set.
ans = max (ans, pre[i] - min (s1))
# erase pre[i-R]
if i - R > = 0 :
s1.remove(pre[i - R])
print (ans)
# Driver code if __name__ = = "__main__" :
L, R = 1 , 3
arr = [ 1 , 2 , 2 , 1 ]
max_sum_subarray(arr, L, R)
|
5
Time Complexity: O (N * log N)
Auxiliary Space: O (N)