Maximum sum two non-overlapping subarrays of given size

11 Jul, 2022
Given an array, we need to find two subarrays with a specific length K such that sum of these subarrays is maximum among all possible choices of subarrays. 
Examples: 
Input : arr[] = [2, 5, 1, 2, 7, 3, 0]
        K = 2
Output : 2 5
         7 3
We can choose two arrays of maximum sum
as [2, 5] and [7, 3], the sum of these two 
subarrays is maximum among all possible 
choices of subarrays of length 2.

Input : arr[] = {10, 1, 3, 15, 30, 40, 4, 50, 2, 1}
        K = 3
Output : 3 15 30 
         40 4 50 
We can solve this problem similar to two pointers method. First we store the prefix sum in a separate array so that any subarray sum can be calculated in constant time. After that we will initialize our two subarray from (N – 2K) and (N – K) indices, where N is the length of the array and K is required subarray length. Then we will move from (N – 2K) index towards 0 and each time we will check whether subarray sum at current index and subarray sum at (current index + K) is greater than previously chosen subarray or not if they are, then update the summation. We can see here that as we need to maximize our sum, we can treat both subarrays independently. At each index we will check subarray sum at current index and subarray sum at K distance away and we will choose maximum sum independently and update the final answer as summation of both these array. In below code index is also taken with sum in form of a pair to actually print the subarrays. Total time complexity of solution will be linear. 
Please see below code for better understanding.
Implemetation:
C++
Java
Python3
C#
Javascript
// C++ program to get maximum sum two non-overlapping// subarrays of same specified length#include <bits/stdc++.h>using namespace std; // Utility method to get sum of subarray// from index i to jint getSubarraySum(int sum[], int i, int j){    if (i == 0)        return sum[j];    else        return (sum[j] - sum[i - 1]);} // Method prints two non-overlapping subarrays of// length K whose sum is maximumvoid maximumSumTwoNonOverlappingSubarray(int arr[],                                      int N, int K){    int sum[N];     // filling prefix sum array    sum[0] = arr[0];    for (int i = 1; i < N; i++)        sum[i] = sum[i - 1] + arr[i];     //    initializing subarrays from (N-2K) and (N-K) indices    pair<int, int> resIndex = make_pair(N - 2 * K, N - K);     //    initializing result sum from above subarray sums    int maxSum2Subarray = getSubarraySum(sum, N - 2 * K, N - K - 1) +                          getSubarraySum(sum, N - K, N - 1);     //    storing second subarray maximum and its starting index    pair<int, int> secondSubarrayMax = make_pair(N - K,                          getSubarraySum(sum, N - K, N - 1));     //    looping from N-2K-1 towards 0    for (int i = N - 2 * K - 1; i >= 0; i--)    {        //    get subarray sum from (current index + K)        int cur = getSubarraySum(sum, i + K, i + 2  * K - 1);         // if (current index + K) sum is more  then update        // secondSubarrayMax        if (cur >= secondSubarrayMax.second)            secondSubarrayMax = make_pair(i + K, cur);         //    now getting complete sum (sum of both subarrays)        cur = getSubarraySum(sum, i, i + K - 1) +              secondSubarrayMax.second;         //    if it is more then update main result        if (cur >= maxSum2Subarray)        {            maxSum2Subarray = cur;            resIndex = make_pair(i, secondSubarrayMax.first);        }    }     //    printing actual subarrays    for (int i = resIndex.first; i < resIndex.first + K; i++)        cout << arr[i] << " ";    cout << endl;     for (int i = resIndex.second; i < resIndex.second + K; i++)        cout << arr[i] << " ";    cout << endl;} //    Driver code to test above methodsint main(){    int arr[] = {2, 5, 1, 2, 7, 3, 0};    int N = sizeof(arr) / sizeof(int);     //    K will be given such that (N >= 2K)    int K = 2;     maximumSumTwoNonOverlappingSubarray(arr, N, K);     return 0;}
// Java program to get maximum sum two non-overlapping// subarrays of same specified lengthclass GFG{ static class pair{    int first, second;    public pair(int first, int second)    {        this.first = first;        this.second = second;    }} // Utility method to get sum of subarray// from index i to jstatic int getSubarraySum(int sum[],                          int i, int j){    if (i == 0)        return sum[j];    else        return (sum[j] - sum[i - 1]);} // Method prints two non-overlapping subarrays of// length K whose sum is maximumstatic void maximumSumTwoNonOverlappingSubarray(int arr[],                                                int N, int K){    int []sum = new int[N];     // filling prefix sum array    sum[0] = arr[0];    for (int i = 1; i < N; i++)        sum[i] = sum[i - 1] + arr[i];     // initializing subarrays from    // (N-2K) and (N-K) indices    pair resIndex = new pair(N - 2 * K, N - K);     // initializing result sum from above subarray sums    int maxSum2Subarray = getSubarraySum(sum, N - 2 * K,                                              N - K - 1) +                          getSubarraySum(sum, N - K, N - 1);     // storing second subarray maximum and    // its starting index    pair secondSubarrayMax = new pair(N - K,                       getSubarraySum(sum, N - K, N - 1));     // looping from N-2K-1 towards 0    for (int i = N - 2 * K - 1; i >= 0; i--)    {        // get subarray sum from (current index + K)        int cur = getSubarraySum(sum, i + K, i + 2 * K - 1);         // if (current index + K) sum is more        // then update secondSubarrayMax        if (cur >= secondSubarrayMax.second)            secondSubarrayMax = new pair(i + K, cur);         // now getting complete sum (sum of both subarrays)        cur = getSubarraySum(sum, i, i + K - 1) +            secondSubarrayMax.second;         // if it is more then update main result        if (cur >= maxSum2Subarray)        {            maxSum2Subarray = cur;            resIndex = new pair(i, secondSubarrayMax.first);        }    }     // printing actual subarrays    for (int i = resIndex.first;             i < resIndex.first + K; i++)        System.out.print(arr[i] + " ");    System.out.println();     for (int i = resIndex.second;             i < resIndex.second + K; i++)        System.out.print(arr[i] + " ");    System.out.println();} // Driver code to test above methodspublic static void main(String[] args){    int arr[] = {2, 5, 1, 2, 7, 3, 0};    int N = arr.length;     // K will be given such that (N >= 2K)    int K = 2;     maximumSumTwoNonOverlappingSubarray(arr, N, K);}} // This code is contributed by Rajput-Ji
# Python3 program to get maximum Sum two# non-overlapping subarrays of same specified length # Utility method to get Sum of# subarray from index i to jdef getSubarraySum(Sum, i, j):     if i == 0:        return Sum[j]    else:        return Sum[j] - Sum[i - 1] # Method prints two non-overlapping subarrays# of length K whose Sum is maximumdef maximumSumTwoNonOverlappingSubarray(arr, N, K):     Sum = [None] * N     # filling prefix Sum array    Sum[0] = arr[0]    for i in range(1, N):        Sum[i] = Sum[i - 1] + arr[i]     # Initializing subarrays from    # (N-2K) and (N-K) indices    resIndex = (N - 2 * K, N - K)     # initializing result Sum from above subarray Sums    maxSum2Subarray = (getSubarraySum(Sum, N - 2 * K, N - K - 1) +                       getSubarraySum(Sum, N - K, N - 1))     # storing second subarray maximum and its starting index    secondSubarrayMax = (N - K, getSubarraySum(Sum, N - K, N - 1))     # looping from N-2K-1 towards 0    for i in range(N - 2 * K - 1, -1, -1):             # get subarray Sum from (current index + K)        cur = getSubarraySum(Sum, i + K, i + 2 * K - 1)         # if (current index + K) Sum is more        # than update secondSubarrayMax        if cur >= secondSubarrayMax[1]:            secondSubarrayMax = (i + K, cur)         # now getting complete Sum (Sum of both subarrays)        cur = (getSubarraySum(Sum, i, i + K - 1) +                           secondSubarrayMax[1])         # If it is more then update main result        if cur >= maxSum2Subarray:                     maxSum2Subarray = cur            resIndex = (i, secondSubarrayMax[0])     # printing actual subarrays    for i in range(resIndex[0], resIndex[0] + K):        print(arr[i], end = " ")    print()     for i in range(resIndex[1], resIndex[1] + K):        print(arr[i], end = " ")    print() # Driver Codeif __name__ == "__main__":     arr = [2, 5, 1, 2, 7, 3, 0]    N = len(arr)     # K will be given such that (N >= 2K)    K = 2     maximumSumTwoNonOverlappingSubarray(arr, N, K) # This code is contributed by Rituraj Jain
// C# program to get maximum sum two non-overlapping// subarrays of same specified lengthusing System; class GFG{ class pair{    public int first, second;    public pair(int first, int second)    {        this.first = first;        this.second = second;    }} // Utility method to get sum of subarray// from index i to jstatic int getSubarraySum(int []sum,                        int i, int j){    if (i == 0)        return sum[j];    else        return (sum[j] - sum[i - 1]);} // Method prints two non-overlapping subarrays of// length K whose sum is maximumstatic void maximumSumTwoNonOverlappingSubarray(int []arr,                                                int N, int K){    int []sum = new int[N];     // filling prefix sum array    sum[0] = arr[0];    for (int i = 1; i < N; i++)        sum[i] = sum[i - 1] + arr[i];     // initializing subarrays from    // (N-2K) and (N-K) indices    pair resIndex = new pair(N - 2 * K, N - K);     // initializing result sum from above subarray sums    int maxSum2Subarray = getSubarraySum(sum, N - 2 * K,                                            N - K - 1) +                        getSubarraySum(sum, N - K, N - 1);     // storing second subarray maximum and    // its starting index    pair secondSubarrayMax = new pair(N - K,                    getSubarraySum(sum, N - K, N - 1));     // looping from N-2K-1 towards 0    for (int i = N - 2 * K - 1; i >= 0; i--)    {        // get subarray sum from (current index + K)        int cur = getSubarraySum(sum, i + K, i + 2 * K - 1);         // if (current index + K) sum is more        // then update secondSubarrayMax        if (cur >= secondSubarrayMax.second)            secondSubarrayMax = new pair(i + K, cur);         // now getting complete sum (sum of both subarrays)        cur = getSubarraySum(sum, i, i + K - 1) +            secondSubarrayMax.second;         // if it is more then update main result        if (cur >= maxSum2Subarray)        {            maxSum2Subarray = cur;            resIndex = new pair(i, secondSubarrayMax.first);        }    }     // printing actual subarrays    for (int i = resIndex.first;            i < resIndex.first + K; i++)        Console.Write(arr[i] + " ");    Console.WriteLine();     for (int i = resIndex.second;            i < resIndex.second + K; i++)        Console.Write(arr[i] + " ");    Console.WriteLine();} // Driver codepublic static void Main(String[] args){    int []arr = {2, 5, 1, 2, 7, 3, 0};    int N = arr.Length;     // K will be given such that (N >= 2K)    int K = 2;     maximumSumTwoNonOverlappingSubarray(arr, N, K);}} // This code is contributed by 29AjayKumar
<script> // JavaScript program to get maximum sum two non-overlapping// subarrays of same specified length  // Utility method to get sum of subarray// from index i to jfunction getSubarraySum(sum, i, j) {    if (i == 0)        return sum[j];    else        return (sum[j] - sum[i - 1]);} // Method prints two non-overlapping subarrays of// length K whose sum is maximumfunction maximumSumTwoNonOverlappingSubarray(arr, N, K) {    let sum = new Array(N);     // filling prefix sum array    sum[0] = arr[0];    for (let i = 1; i < N; i++)        sum[i] = sum[i - 1] + arr[i];     // initializing subarrays from (N-2K) and (N-K) indices    let resIndex = [N - 2 * K, N - K];     // initializing result sum from above subarray sums    let maxSum2Subarray = getSubarraySum(sum, N - 2 * K, N - K - 1) +        getSubarraySum(sum, N - K, N - 1);     // storing second subarray maximum and its starting index    let secondSubarrayMax = [N - K,    getSubarraySum(sum, N - K, N - 1)];     // looping from N-2K-1 towards 0    for (let i = N - 2 * K - 1; i >= 0; i--) {        // get subarray sum from (current index + K)        let cur = getSubarraySum(sum, i + K, i + 2 * K - 1);         // if (current index + K) sum is more then update        // secondSubarrayMax        if (cur >= secondSubarrayMax[1])            secondSubarrayMax = [i + K, cur];         // now getting complete sum (sum of both subarrays)        cur = getSubarraySum(sum, i, i + K - 1) +            secondSubarrayMax[1];         // if it is more then update main result        if (cur >= maxSum2Subarray) {            maxSum2Subarray = cur;            resIndex = [i, secondSubarrayMax[0]];        }    }     // printing actual subarrays    for (let i = resIndex[0]; i < resIndex[0] + K; i++)        document.write(arr[i] + " ");    document.write("<br>");     for (let i = resIndex[1]; i < resIndex[1] + K; i++)        document.write(arr[i] + " ");    document.write("<br>");} // Driver code to test above methods let arr = [2, 5, 1, 2, 7, 3, 0];let N = arr.length; // K will be given such that (N >= 2K)let K = 2; maximumSumTwoNonOverlappingSubarray(arr, N, K); </script>
2 5 
7 3 
Time Complexity: O(n) , where n is the size of the given array.Auxiliary Space: O(n)
This article is contributed by Utkarsh Trivedi. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks. 
rituraj_jain
Rajput-Ji
29AjayKumar
gfgking
anshulpro27
hardikkoriintern
prefix-sum
subarray
subarray-sum
Arrays
prefix-sum
Arrays
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.