Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Maximum Prefix Sum possible by merging two given arrays

  • Last Updated : 23 Apr, 2021

Given two arrays A[] and B[] consisting of N and M integers respectively, the task is to calculate the maximum prefix sum that can be obtained by merging the two arrays.

Examples:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input : A[] = {2, -1, 4, -5}, B[]={4, -3, 12, 4, -3}
Output : 22
Explanation: Merging the two arrays to generate the sequence {2, 4, -1, -3, 4, 12, 4, -5, -3}. Maximum prefix sum = Sum of {arr[0], …, arr[6]} = 22.



Input: A[] = {2, 1, 13, 5, 14}, B={-1, 4, -13}
Output: 38
Explanation: Merging the two arrays to generate the sequence {2, 1, -1, 13, 5, 14, -13}. Maximum prefix sum = Sum of {arr[0], …, arr[6]} = 38.

Naive Approach: The simplest approach is to use Recursion, which can be optimized using Memoization. Follow the steps below to solve the problem:

  • Initialize a map<pair<int, int>, int> dp[] for memorization.
  • Define a recursive function, say maxPresum(x, y) to find the maximum prefix sum:
    • If dp[{x, y}] is already calculated, then return dp[{x, y}].
    • Otherwise, if x==N || y==M, then return 0.
    • Update dp[{x, y}] as dp[{x, y}] = max(dp[{x, y}, a[x]+maxPresum(x+1, y), b[y]+maxPresum(x, y+1)) and then return dp[{x, y}].
  • Print the maximum prefix sum as maxPresum(0, 0).

Below is the implementation of the above approach:

C++




// C++ implementation of above approach
#include <bits/stdc++.h>
 
#define int long long
using namespace std;
 
// Stores the dp states
map<pair<int, int>, int> dp;
 
// Recursive Function to calculate the maximum
// prefix sum ontained by merging two arrays
int maxPreSum(vector<int> a, vector<int> b,
              int x, int y)
{
    // If subproblem is already computed
    if (dp.find({ x, y }) != dp.end())
        return dp[{ x, y }];
 
    // If x >= N or y >= M
    if (x == a.size() && y == b.size())
        return 0;
 
    int curr = dp[{ x, y }];
 
    // If x < N
    if (x == a.size()) {
        curr = max(curr, b[y]
                             + maxPreSum(a, b, x, y + 1));
    }
    // If y<M
    else if (y == b.size()) {
        curr = max(curr,
                   a[x] + maxPreSum(a, b, x + 1, y));
    }
 
    // Otherwise
    else {
        curr = max({ curr,
                     a[x] + maxPreSum(a, b, x + 1, y),
                     b[y] + maxPreSum(a, b, x, y + 1) });
    }
    return dp[{ x, y }] = curr;
}
// Driver Code
signed main()
{
    vector<int> A = { 2, 1, 13, 5, 14 };
    vector<int> B = { -1, 4, -13 };
    cout << maxPreSum(A, B, 0, 0) << endl;
    return 0;
}

C#




// C# implementation of above approach
using System;
using System.Collections.Generic;
 
class GFG{
     
// Stores the dp states
static Dictionary<Tuple<int,
                        int>, int> dp = new Dictionary<Tuple<int,
                                                             int>, int>();
 
// Recursive Function to calculate the maximum
// prefix sum ontained by merging two arrays
static int maxPreSum(int[] a, int[] b, int x, int y)
{
     
    // If subproblem is already computed
    if (dp.ContainsKey(new Tuple<int, int>(x, y)))
        return dp[new Tuple<int, int>(x, y)];
     
    // If x >= N or y >= M
    if (x == a.Length && y == b.Length)
        return 0;
     
    int curr = 0;
    if (dp.ContainsKey(new Tuple<int, int>(x, y)))
    {
        curr = dp[new Tuple<int, int>(x, y)];
    }
     
    // If x < N
    if (x == a.Length)
    {
        curr = Math.Max(curr, b[y] + maxPreSum(
            a, b, x, y + 1));
    }
     
    // If y<M
    else if (y == b.Length)
    {
        curr = Math.Max(curr, a[x] + maxPreSum(
            a, b, x + 1, y));
    }
     
    // Otherwise
    else
    {
        int max = Math.Max(a[x] + maxPreSum(a, b, x + 1, y),
                           b[y] + maxPreSum(a, b, x, y + 1));
        curr = Math.Max(curr, max);
    }
    dp[new Tuple<int,int>(x, y)] = curr;
    return dp[new Tuple<int, int>(x, y)];
}
 
// Driver code
static void Main()
{
    int[] A = { 2, 1, 13, 5, 14 };
    int[] B = { -1, 4, -13 };
     
    Console.WriteLine(maxPreSum(A, B, 0, 0));
}
}
 
// This code is contributed by divyesh072019
Output: 
38

 

Time Complexity: O(N·M)
Auxiliary Space: O(N*M)

Efficient Approach: The above approach can be optimized based on the observation that the maximum prefix sum is equal to the sum of the maximum prefix sum of arrays A[] and B[]. Follow the steps below to solve the problem:

  • Calculate the maximum prefix sum of array A[] and store it in a variable, say X.
  • Calculate the maximum prefix sum of array B[] and store it in a variable, say Y.
  • Print the sum of X and Y.

Below is the implementation of the above approach: 

C++




// C++ Program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
int maxPresum(vector<int> a, vector<int> b)
{
    // Stores the maximum prefix
    // sum of the array A[]
    int X = max(a[0], 0);
 
    // Traverse the array A[]
    for (int i = 1; i < a.size(); i++) {
        a[i] += a[i - 1];
        X = max(X, a[i]);
    }
 
    // Stores the maximum prefix
    // sum of the array B[]
    int Y = max(b[0], 0);
 
    // Traverse the array B[]
    for (int i = 1; i < b.size(); i++) {
        b[i] += b[i - 1];
        Y = max(Y, b[i]);
    }
    return X + Y;
}
 
// Driver code
int main()
{
    vector<int> A = { 2, -1, 4, -5 };
    vector<int> B = { 4, -3, 12, 4, -3 };
    cout << maxPresum(A, B) << endl;
}

Java




// Java Program to implement
// the above approach
import java.util.*;
class GFG {
 
  static int maxPresum(int [] a, int [] b)
  {
     
    // Stores the maximum prefix
    // sum of the array A[]
    int X = Math.max(a[0], 0);
 
    // Traverse the array A[]
    for (int i = 1; i < a.length; i++)
    {
      a[i] += a[i - 1];
      X = Math.max(X, a[i]);
    }
 
    // Stores the maximum prefix
    // sum of the array B[]
    int Y = Math.max(b[0], 0);
 
    // Traverse the array B[]
    for (int i = 1; i < b.length; i++) {
      b[i] += b[i - 1];
      Y = Math.max(Y, b[i]);
    }
    return X + Y;
  }
 
  // Driver code
  public static void main(String [] args)
  {
    int [] A = { 2, -1, 4, -5 };
    int [] B = { 4, -3, 12, 4, -3 };
    System.out.print(maxPresum(A, B));
  }
}
 
// This code is contributed by ukasp.

Python3




# Python3 implementation of the
# above approach
 
def maxPresum(a, b) :
     
    # Stores the maximum prefix
    # sum of the array A[]
    X = max(a[0], 0)
 
    # Traverse the array A[]
    for i in range(1, len(a)):
        a[i] += a[i - 1]
        X = max(X, a[i])
     
    # Stores the maximum prefix
    # sum of the array B[]
    Y = max(b[0], 0)
 
    # Traverse the array B[]
    for i in range(1, len(b)):
        b[i] += b[i - 1]
        Y = max(Y, b[i])
     
    return X + Y
 
# Driver code
 
A = [ 2, -1, 4, -5 ]
B = [ 4, -3, 12, 4, -3 ]
print(maxPresum(A, B))
 
# This code is contributed by code_hunt.

C#




// C# Program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG {
 
  static int maxPresum(List<int> a, List<int> b)
  {
     
    // Stores the maximum prefix
    // sum of the array A[]
    int X = Math.Max(a[0], 0);
 
    // Traverse the array A[]
    for (int i = 1; i < a.Count; i++)
    {
      a[i] += a[i - 1];
      X = Math.Max(X, a[i]);
    }
 
    // Stores the maximum prefix
    // sum of the array B[]
    int Y = Math.Max(b[0], 0);
 
    // Traverse the array B[]
    for (int i = 1; i < b.Count; i++) {
      b[i] += b[i - 1];
      Y = Math.Max(Y, b[i]);
    }
    return X + Y;
  }
 
  // Driver code
  static void Main()
  {
    List<int> A = new List<int>(new int[]{ 2, -1, 4, -5 });
    List<int> B = new List<int>(new int[]{ 4, -3, 12, 4, -3 });
    Console.WriteLine(maxPresum(A, B));
  }
}
 
// This code is contributed by divyeshrabadiya07.

Javascript




<script>
 
    // Javascript Program to implement
    // the above approach
     
    function maxPresum(a, b)
    {
 
      // Stores the maximum prefix
      // sum of the array A[]
      let X = Math.max(a[0], 0);
 
      // Traverse the array A[]
      for (let i = 1; i < a.length; i++)
      {
        a[i] += a[i - 1];
        X = Math.max(X, a[i]);
      }
 
      // Stores the maximum prefix
      // sum of the array B[]
      let Y = Math.max(b[0], 0);
 
      // Traverse the array B[]
      for (let i = 1; i < b.length; i++) {
        b[i] += b[i - 1];
        Y = Math.max(Y, b[i]);
      }
      return X + Y;
    }
     
    let A = [ 2, -1, 4, -5 ];
    let B = [ 4, -3, 12, 4, -3 ];
    document.write(maxPresum(A, B));
   
</script>
Output: 
22

 

Time Complexity: O(M+N)
Auxiliary Space: O(1) 




My Personal Notes arrow_drop_up
Recommended Articles
Page :