Maximum Prefix Sum possible by merging two given arrays
Last Updated :
04 Jan, 2023
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 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 obtained 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;
}
Java
import java.util.HashMap;
import java.util.Map;
public class Main {
// Stores the dp states
static Map<Tuple, Integer> dp = new HashMap<>();
// Recursive Function to calculate the maximum
// prefix sum obtained 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(x, y))) {
return dp.get(new Tuple(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(x, y))) {
curr = dp.get(new Tuple(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.put(new Tuple(x, y), curr);
return dp.get(new Tuple(x, y));
}
// Driver code
public static void main(String[] args)
{
int[] A = { 2, 1, 13, 5, 14 };
int[] B = { -1, 4, -13 };
System.out.println(maxPreSum(A, B, 0, 0));
}
// Tuple class definition
static class Tuple {
int x;
int y;
public Tuple(int x, int y)
{
this.x = x;
this.y = y;
}
@Override public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override public boolean equals(Object obj)
{
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Tuple other = (Tuple)obj;
if (x != other.x) {
return false;
}
if (y != other.y) {
return false;
}
return true;
}
}
}
// This code is contributed by phasing17.
Python3
# Python3 implementation of above approach
# Stores the dp states
dp = {}
# Recursive Function to calculate the maximum
# prefix sum obtained by merging two arrays
def maxPreSum(a, b, x, y):
# If subproblem is already computed
if (x, y) in dp:
return dp[(x, y)]
# If x >= N or y >= M
if x == len(a) and y == len(b):
return 0;
curr = 0;
if (x, y) in dp:
curr = dp[(x, y)]
# If x < N
if x == len(a):
curr = max(curr, b[y] + maxPreSum(a, b, x, y + 1));
# If y<M
elif (y == len(b)):
curr = max(curr, a[x] + maxPreSum(a, b, x + 1, y));
# Otherwise
else:
maxs = max(a[x] + maxPreSum(a, b, x + 1, y), b[y] + maxPreSum(a, b, x, y + 1));
curr = max(curr, maxs);
dp[(x, y)] = curr;
return dp[(x, y)]
# Driver code
A = [2, 1, 13, 5, 14];
B = [-1, 4, -13 ];
print(maxPreSum(A, B, 0, 0));
# This code is contributed by phasing17
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 obtained 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
JavaScript
// JavaScript implementation of above approach
// Stores the dp states
const dp = {};
// Recursive Function to calculate the maximum
// prefix sum obtained by merging two arrays
function maxPreSum(a, b, x, y) {
// If subproblem is already computed
if (x in dp && y in dp[x]) {
return dp[x][y];
}
// If x >= N or y >= M
if (x === a.length && y === b.length) {
return 0;
}
let curr = 0;
if (x in dp && y in dp[x]) {
curr = dp[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 {
const maxs = Math.max(
a[x] + maxPreSum(a, b, x + 1, y),
b[y] + maxPreSum(a, b, x, y + 1)
);
curr = Math.max(curr, maxs);
}
if (!(x in dp)) {
dp[x] = {};
}
dp[x][y] = curr;
return dp[x][y];
}
// Driver code
const A = [2, 1, 13, 5, 14];
const B = [-1, 4, -13];
console.log(maxPreSum(A, B, 0, 0));
// This code is contributed by phasing17
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>
Time Complexity: O(M+N)
Auxiliary Space: O(1)
Similar Reads
Maximum possible pair sum at most K from two Arrays Given two arrays arr1[] and arr2[] of sizes N and M and an integer K, the task is to find the maximum possible sum pair from two arrays such that the sum is at most K. Note: You have to take one element from each array. Examples: Input: arr1[] = {5, 4, 1, 2, 3}, arr2[] = {30, 20, 40, 10}, K = 30Outp
12 min read
Maximum possible Array sum after performing given operations Given array arr[] of positive integers, an integer Q, and arrays X[] and Y[] of size Q. For each element in arrays X[] and Y[], we can perform the below operations: For each query from array X[] and Y[], select at most X[i] elements from array arr[] and replace all the selected elements with integer
9 min read
Maximum K-digit number possible from subsequences of two given arrays Given two arrays arr1[] and arr2[] of length M and N consisting of digits [0, 9] representing two numbers and an integer K(K ? M + N), the task is to find the maximum K-digit number possible by selecting subsequences from the given arrays such that the relative order of the digits is the same as in
12 min read
Maximum Sum Path in Two Arrays Given two sorted arrays having some elements in common. Find the sum of the maximum sum path to reach from the beginning of any array to the end of any of the two arrays. We can switch from one array to another array only at common elements. Note: The common elements do not have to be at the same in
14 min read
Maximum sum by picking elements from two arrays in order | Set 2 Given two arrays A[] and B[], each of size N, and two integers X and Y denoting the maximum number of elements that can be picked from A[] and B[] respectively, the task is to find the maximum possible sum by selecting N elements in such a way that for any index i, either A[i] or B[i] can be chosen.
10 min read