Max sum path in two arrays

Last Updated : 8 Jul, 2026

Given two sorted arrays of distinct integers, arr1[] and arr2[], which may have some common elements, find the maximum sum of a path from the beginning of any array to the end of any array. You may switch from one array to the other only at common elements.

Note:  When switching, count the common element only once.

Examples: 

Input: arr1[] = [2, 3, 7, 10, 12], arr2[] = [1, 5, 7, 8]
Output: 35
Explanation: The path will be (1 + 5 + 7 + 10 + 12) = 35, where 1 and 5 come from arr2 and then 7 is common so we switch to arr1 and add 10 and 12.

Input: arr1[] = [1, 2, 3], arr2 = [3, 4, 5]
Output: 15
Explanation: The path will be (1 + 2 + 3 + 4 + 5) = 15.

Input: arr1[] = [2, 3, 7, 10, 12, 15, 30, 34], arr2[] = [1, 5, 7, 8, 10, 15, 16, 19]
Output: 122
Explanation: 122 is sum of 1, 5, 7, 8, 10, 12, 15, 30, 34. Start from the first element of arr2 which is 1, then move to 5, then 7. From 7 switch to arr1 (as 7 is common), then traverse the remaining arr1.

Try It Yourself
redirect icon

[Naive Approach] Using Recursion - O(2^k) Time and O(n + m) Space

We can explore all possible valid paths. We traverse the array recursively, and every time we land on a common element, you branch your recursive function into two choices: stay in the current array or switch to the other. Then return the path that yields the highest sum. If there are k common elements we can do this in 2^k time complexity.

C++
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

// Helper to find the index of a target (returns -1 if not found)
int indexOf(vector<int> arr, int target)
{
    for (int i = 0; i < arr.size(); i++)
    {
        if (arr[i] == target)
            return i;
    }
    return -1;
}

// f = true means we are currently in arr1. f = false means arr2.
int solve(int i, int j, bool f, vector<int> arr1, vector<int> arr2)
{

    // Base cases: reached the end of the active array
    if (f && i == arr1.size())
        return 0;
    if (!f && j == arr2.size())
        return 0;

    if (f)
    {
        int matchIdx = indexOf(arr2, arr1[i]);

        // Path 1: Stay in array 1
        int stay = arr1[i] + solve(i + 1, j, true, arr1, arr2);

        // Path 2: Switch to array 2 (only valid if it's a common element)
        int swap = (matchIdx != -1) ? arr1[i] + solve(i + 1, matchIdx + 1, false, arr1, arr2) : 0;

        return max(stay, swap);
    }
    else
    {
        int matchIdx = indexOf(arr1, arr2[j]);

        // Path 1: Stay in array 2
        int stay = arr2[j] + solve(i, j + 1, false, arr1, arr2);

        // Path 2: Switch to array 1
        int swap = (matchIdx != -1) ? arr2[j] + solve(matchIdx + 1, j + 1, true, arr1, arr2) : 0;

        return max(stay, swap);
    }
}
int maxPathSum(vector<int> arr1, vector<int> arr2)
{
    // Try starting from both arrays and take the maximum
    int startInArr1 = solve(0, 0, true, arr1, arr2);
    int startInArr2 = solve(0, 0, false, arr1, arr2);

    return max(startInArr1, startInArr2);
}

int main()
{
    vector<int> arr1 = {2, 3, 7, 10, 12, 15, 30, 34};
    vector<int> arr2 = {1, 5, 7, 8, 10, 15, 16, 19};

    cout << maxPathSum(arr1, arr2);
    return 0;
}
Java
class Solution {
    // Helper to find the index of a target (returns -1 if
    // not found)
    int indexOf(int[] arr, int target)
    {
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == target)
                return i;
        }
        return -1;
    }

    // f = true means we are currently in arr1. f = false
    // means arr2.
    public int solve(int i, int j, boolean f, int[] arr1,
                     int[] arr2)
    {

        // Base cases: reached the end of the active array
        if (f && i == arr1.length)
            return 0;
        if (!f && j == arr2.length)
            return 0;

        if (f) {
            int matchIdx = indexOf(arr2, arr1[i]);

            // Path 1: Stay in array 1
            int stay = arr1[i]
                       + solve(i + 1, j, true, arr1, arr2);

            // Path 2: Switch to array 2 (only valid if it's
            // a common element)
            int swap
                = (matchIdx != -1)
                      ? arr1[i]
                            + solve(i + 1, matchIdx + 1,
                                    false, arr1, arr2)
                      : 0;

            return Math.max(stay, swap);
        }
        else {
            int matchIdx = indexOf(arr1, arr2[j]);

            // Path 1: Stay in array 2
            int stay = arr2[j]
                       + solve(i, j + 1, false, arr1, arr2);

            // Path 2: Switch to array 1
            int swap
                = (matchIdx != -1)
                      ? arr2[j]
                            + solve(matchIdx + 1, j + 1,
                                    true, arr1, arr2)
                      : 0;

            return Math.max(stay, swap);
        }
    }

    public int maxPathSum(int[] arr1, int[] arr2)
    {
        // Try starting from both arrays and take the
        // maximum
        int startInArr1 = solve(0, 0, true, arr1, arr2);
        int startInArr2 = solve(0, 0, false, arr1, arr2);

        return Math.max(startInArr1, startInArr2);
    }

    public static void main(String[] args)
    {
        // Create an instance of Solution to call the
        // non-static methods
        Solution obj = new Solution();

        int[] arr1 = { 2, 3, 7, 10, 12 };
        int[] arr2 = { 1, 5, 7, 8 };

        int res = obj.maxPathSum(arr1, arr2);

        System.out.println(res); // Expected Output: 35
    }
}
Python
def indexOf(arr, target):
    for i in range(len(arr)):
        if arr[i] == target:
            return i
    return -1

# f = true means we are currently in arr1. f = false means arr2.


def solve(i, j, f, arr1, arr2):
    # Base cases: reached the end of the active array
    if f and i == len(arr1):
        return 0
    if not f and j == len(arr2):
        return 0

    if f:
        matchIdx = indexOf(arr2, arr1[i])

        # Path 1: Stay in array 1
        stay = arr1[i] + solve(i + 1, j, True, arr1, arr2)

        # Path 2: Switch to array 2 (only valid if it's a common element)
        swap = arr1[i] + solve(i + 1, matchIdx + 1, False,
                               arr1, arr2) if matchIdx != -1 else 0

        return max(stay, swap)
    else:
        matchIdx = indexOf(arr1, arr2[j])

        # Path 1: Stay in array 2
        stay = arr2[j] + solve(i, j + 1, False, arr1, arr2)

        # Path 2: Switch to array 1
        swap = arr2[j] + solve(matchIdx + 1, j + 1, True,
                               arr1, arr2) if matchIdx != -1 else 0

        return max(stay, swap)


def maxPathSum(arr1, arr2):
    # Try starting from both arrays and take the maximum
    startInArr1 = solve(0, 0, True, arr1, arr2)
    startInArr2 = solve(0, 0, False, arr1, arr2)

    return max(startInArr1, startInArr2)


arr1 = [2, 3, 7, 10, 12, 15, 30, 34]
arr2 = [1, 5, 7, 8, 10, 15, 16, 19]

print(maxPathSum(arr1, arr2))
C#
using System;

public class Solution {
    // Helper to find the index of a target (returns -1 if
    // not found)
    int indexOf(int[] arr, int target)
    {
        for (int i = 0; i < arr.Length; i++) {
            if (arr[i] == target)
                return i;
        }
        return -1;
    }

    // f = true means we are currently in arr1. f = false
    // means arr2.
    public int solve(int i, int j, bool f, int[] arr1,
                     int[] arr2)
    {

        // Base cases: reached the end of the active array
        if (f && i == arr1.Length)
            return 0;
        if (!f && j == arr2.Length)
            return 0;

        if (f) {
            int matchIdx = indexOf(arr2, arr1[i]);

            // Path 1: Stay in array 1
            int stay = arr1[i]
                       + solve(i + 1, j, true, arr1, arr2);

            // Path 2: Switch to array 2 (only valid if it's
            // a common element)
            int swap
                = (matchIdx != -1)
                      ? arr1[i]
                            + solve(i + 1, matchIdx + 1,
                                    false, arr1, arr2)
                      : 0;

            return Math.Max(stay, swap);
        }
        else {
            int matchIdx = indexOf(arr1, arr2[j]);

            // Path 1: Stay in array 2
            int stay = arr2[j]
                       + solve(i, j + 1, false, arr1, arr2);

            // Path 2: Switch to array 1
            int swap
                = (matchIdx != -1)
                      ? arr2[j]
                            + solve(matchIdx + 1, j + 1,
                                    true, arr1, arr2)
                      : 0;

            return Math.Max(stay, swap);
        }
    }

    public int maxPathSum(int[] arr1, int[] arr2)
    {
        // Try starting from both arrays and take the
        // maximum
        int startInArr1 = solve(0, 0, true, arr1, arr2);
        int startInArr2 = solve(0, 0, false, arr1, arr2);

        return Math.Max(startInArr1, startInArr2);
    }

    public static void Main(string[] args)
    {
        // Create an instance of Solution to call the
        // non-static methods
        Solution obj = new Solution();

        int[] arr1 = { 2, 3, 7, 10, 12 };
        int[] arr2 = { 1, 5, 7, 8 };

        int res = obj.maxPathSum(arr1, arr2);

        Console.WriteLine(res); // Expected Output: 35
    }
}
JavaScript
function indexOf(arr, target)
{
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] === target) {
            return i;
        }
    }
    return -1;
}

// f = true means we are currently in arr1. f = false means
// arr2.
function solve(i, j, f, arr1, arr2)
{
    // Base cases: reached the end of the active array
    if (f && i === arr1.length) {
        return 0;
    }
    if (!f && j === arr2.length) {
        return 0;
    }

    if (f) {
        let matchIdx = indexOf(arr2, arr1[i]);

        // Path 1: Stay in array 1
        let stay
            = arr1[i] + solve(i + 1, j, true, arr1, arr2);

        // Path 2: Switch to array 2 (only valid if it's a
        // common element)
        let swap = (matchIdx !== -1)
                       ? arr1[i]
                             + solve(i + 1, matchIdx + 1,
                                     false, arr1, arr2)
                       : 0;

        return Math.max(stay, swap);
    }
    else {
        let matchIdx = indexOf(arr1, arr2[j]);

        // Path 1: Stay in array 2
        let stay
            = arr2[j] + solve(i, j + 1, false, arr1, arr2);

        // Path 2: Switch to array 1
        let swap = (matchIdx !== -1)
                       ? arr2[j]
                             + solve(matchIdx + 1, j + 1,
                                     true, arr1, arr2)
                       : 0;

        return Math.max(stay, swap);
    }
}

function maxPathSum(arr1, arr2)
{
    // Try starting from both arrays and take the maximum
    let startInArr1 = solve(0, 0, true, arr1, arr2);
    let startInArr2 = solve(0, 0, false, arr1, arr2);

    return Math.max(startInArr1, startInArr2);
}

let arr1 = [ 2, 3, 7, 10, 12, 15, 30, 34 ];
let arr2 = [ 1, 5, 7, 8, 10, 15, 16, 19 ];

console.log(maxPathSum(arr1, arr2));

Output
122

Using Two Pointers and Prefix Sum Traversal - O(n + m) Time and O(1) Space

The idea is to do something similar to the merge process of merge sort. This involves calculating the sum of elements between all common points of both arrays. Whenever there is a common point, compare the two sums and add the maximum of two to the result.

Follow the steps below to solve the given problem:

  • Initialize result = 0, sum1 = 0, and sum2 = 0, where sum1 and sum2 store the sums between consecutive common elements.
  • Traverse both sorted arrays simultaneously.
  • If arr1[i] < arr2[j], add arr1[i] to sum1; otherwise, if arr2[j] < arr1[i], add arr2[j] to sum2.
  • If both elements are equal, add max(sum1, sum2) and the common element to result, then reset sum1 and sum2.
  • After traversal, add the larger of the remaining sums to result.

The good thing about this approach is, we cover all elements before reaching a common point. So when we are at a common point, we compare the two sums and decide which one to choose.


C++
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int maxPathSum(vector<int> &arr1, vector<int> &arr2)
{

    int i = 0, j = 0;
    int m = arr1.size(), n = arr2.size();

    int result = 0, sum1 = 0, sum2 = 0;

    // Using two pointers to iterate over two arrays
    while (i < m && j < n)
    {

        // if arr1 is smaller than arr2, 
        // incresing arr1 and adding its value to sum1
        if (arr1[i] < arr2[j])
        {
            sum1 += arr1[i++];
        }

        // if arr2 is smaller than arr1, 
        // incresing arr2 and adding its value to sum
        else if (arr1[i] > arr2[j])
        {
            sum2 += arr2[j++];
        }

        // if arr1=arr2, checking the maximum sum obtained from both the arrays
        // updating result and sum1 and sum2 is again changed to zero
        else
        {
            result += max(sum1, sum2) + arr1[i];
            sum1 = 0;
            sum2 = 0;
            i++;
            j++;
        }
    }

    // if jth pointer reaches end
    while (i < m)
        sum1 += arr1[i++];

    // if ith pointer reaches end
    while (j < n)
        sum2 += arr2[j++];

    // last maximum sum to be added after the end of the loop
    result += max(sum1, sum2);

    return result;
}

int main()
{
    vector<int> arr1 = {2, 3, 7, 10, 12, 15, 30, 34};
    vector<int> arr2 = {1, 5, 7, 8, 10, 15, 16, 19};

    cout << maxPathSum(arr1, arr2);
    return 0;
}
Java
import java.util.Arrays;

class GFG {
    public static int maxPathSum(int[] arr1, int[] arr2)
    {
        int i = 0, j = 0;
        int m = arr1.length, n = arr2.length;

        int result = 0, sum1 = 0, sum2 = 0;

        // Using two pointers to iterate over two arrays
        while (i < m && j < n) {

            // if arr1 is smaller than arr2, incresing arr1
            // and adding its value to sum1
            if (arr1[i] < arr2[j]) {
                sum1 += arr1[i++];
            }
            
            // if arr2 is smaller than arr1, incresing arr2
            // and adding its value to sum
            else if (arr1[i] > arr2[j]) {
                sum2 += arr2[j++];
            }
            
            // if arr1=arr2, checking the maximum sum
            // obtained from both the arrays updating result
            // and sum1 and sum2 is again changed to zero
            else {
                result += Math.max(sum1, sum2) + arr1[i];
                sum1 = 0;
                sum2 = 0;
                i++;
                j++;
            }
        }

        // if jth pointer reaches end
        while (i < m)
            sum1 += arr1[i++];
            
        // if ith pointer reaches end
        while (j < n)
            sum2 += arr2[j++];
            
        // last maximum sum to be added after the end of the
        // loop
        result += Math.max(sum1, sum2);

        return result;
    }

    public static void main(String[] args)
    {
        int[] arr1 = { 2, 3, 7, 10, 12, 15, 30, 34 };
        int[] arr2 = { 1, 5, 7, 8, 10, 15, 16, 19 };
        System.out.println(maxPathSum(arr1, arr2));
    }
}
Python
def maxPathSum(arr1, arr2):
    i = 0
    j = 0
    m = len(arr1)
    n = len(arr2)

    result = 0
    sum1 = 0
    sum2 = 0

    # Using two pointers to iterate over two arrays
    while i < m and j < n:

        # if arr1 is smaller than arr2, 
        # incresing arr1 and adding its value to sum1
        if arr1[i] < arr2[j]:
            sum1 += arr1[i]
            i += 1

        # if arr2 is smaller than arr1, 
        # incresing arr2 and adding its value to sum
        elif arr1[i] > arr2[j]:
            sum2 += arr2[j]
            j += 1

        # if arr1=arr2, checking the maximum sum obtained from both the arrays
        # updating result and sum1 and sum2 is again changed to zero
        else:
            result += max(sum1, sum2) + arr1[i]
            sum1 = 0
            sum2 = 0
            i += 1
            j += 1

    # if jth pointer reaches end
    while i < m:
        sum1 += arr1[i]
        i += 1

    # if ith pointer reaches end
    while j < n:
        sum2 += arr2[j]
        j += 1

    # last maximum sum to be added after the end of the loop
    result += max(sum1, sum2)

    return result


if __name__ == '__main__':
    arr1 = [2, 3, 7, 10, 12, 15, 30, 34]
    arr2 = [1, 5, 7, 8, 10, 15, 16, 19]
    print(maxPathSum(arr1, arr2))
C#
using System;

public class GFG {
    public static int maxPathSum(int[] arr1, int[] arr2) {
        int i = 0, j = 0;
        int m = arr1.Length, n = arr2.Length;

        int result = 0, sum1 = 0, sum2 = 0;

        // Using two pointers to iterate over two arrays
        while (i < m && j < n) {

            // if arr1 is smaller than arr2, 
            // increasing arr1 and adding its value to sum1
            if (arr1[i] < arr2[j]) {
                sum1 += arr1[i];
                i++;
            }

            // if arr2 is smaller than arr1, 
            // increasing arr2 and adding its value to sum
            else if (arr1[i] > arr2[j]) {
                sum2 += arr2[j];
                j++;
            }

            // if arr1=arr2, checking the maximum sum obtained from both the arrays
            // updating result and sum1 and sum2 is again changed to zero
            else {
                result += Math.Max(sum1, sum2) + arr1[i];
                sum1 = 0;
                sum2 = 0;
                i++;
                j++;
            }
        }

        // if jth pointer reaches end
        while (i < m) {
            sum1 += arr1[i];
            i++;
        }

        // if ith pointer reaches end
        while (j < n) {
            sum2 += arr2[j];
            j++;
        }

        // last maximum sum to be added after the end of the loop
        result += Math.Max(sum1, sum2);

        return result;
    }

    public static void Main(string[] args) {
        int[] arr1 = {2, 3, 7, 10, 12, 15, 30, 34};
        int[] arr2 = {1, 5, 7, 8, 10, 15, 16, 19};
        Console.WriteLine(maxPathSum(arr1, arr2));
    }
}
JavaScript
function maxPathSum(arr1, arr2)
{
    let i = 0, j = 0;
    let m = arr1.length, n = arr2.length;

    let result = 0, sum1 = 0, sum2 = 0;

    // Using two pointers to iterate over two arrays
    while (i < m && j < n) {

        // if arr1 is smaller than arr2, increasing arr1 and
        // adding its value to sum1
        if (arr1[i] < arr2[j]) {
            sum1 += arr1[i++];
        }

        // if arr2 is smaller than arr1, increasing arr2 and
        // adding its value to sum
        else if (arr1[i] > arr2[j]) {
            sum2 += arr2[j++];
        }

        // if arr1=arr2, checking the maximum sum obtained
        // from both the arrays updating result and sum1 and
        // sum2 is again changed to zero
        else {
            result += Math.max(sum1, sum2) + arr1[i];
            sum1 = 0;
            sum2 = 0;
            i++;
            j++;
        }
    }

    // if jth pointer reaches end
    while (i < m)
        sum1 += arr1[i++];

    // if ith pointer reaches end
    while (j < n)
        sum2 += arr2[j++];

    // last maximum sum to be added after the end of the
    // loop
    result += Math.max(sum1, sum2);

    return result;
}

// Driver code
let arr1 = [ 2, 3, 7, 10, 12, 15, 30, 34 ];
let arr2 = [ 1, 5, 7, 8, 10, 15, 16, 19 ];

console.log(maxPathSum(arr1, arr2));

Output
122
Comment