Skip to content
Related Articles

Related Articles

Maximum Prefix Sum possible by merging two given arrays
  • Last Updated : 12 Mar, 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:

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 memoization.
  • 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.
Output: 
22

 

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

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.

My Personal Notes arrow_drop_up
Recommended Articles
Page :