Maximum absolute diff of sum of two contiguous Subarrays

Last Updated : 6 Jul, 2026

Given an array of integers arr[]. Find two non-overlapping contiguous sub-arrays such that the absolute difference between the sum of two sub-arrays is maximum.

Examples:

Input: arr[] = [-2, -3, 4, -1, -2, 1, 5, -3]
Output: 12
Explanation: Two subarrays are [-2, -3] and [4, -1, -2, 1, 5].

Input: arr[] = [2, -1, -2, 1, -4, 2, 8]
Output: 16
Explanation: Two subarrays are [-1, -2, 1, -4] and [2, 8].

Try It Yourself
redirect icon

[Naive Approach] Check Every Pair of Non-Overlapping Subarrays - O(n ^ 4) Time and O(1) Space

The idea is to generate all possible pairs of non-overlapping subarrays. For every pair, compute the sum of both subarrays and calculate their absolute difference. The maximum such difference is the answer.

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

int maxDiffSubArrays(vector<int> &arr)
{
    int n = arr.size();

    int res = INT_MIN;

    // Generate first subarray
    for (int i = 0; i < n; i++)
    {

        int sum1 = 0;

        for (int j = i; j < n; j++)
        {

            sum1 += arr[j];

            // Generate second non-overlapping subarray
            for (int k = j + 1; k < n; k++)
            {

                int sum2 = 0;

                for (int l = k; l < n; l++)
                {

                    sum2 += arr[l];

                    // Update maximum absolute difference
                    res = max(res, abs(sum1 - sum2));
                }
            }
        }
    }

    // Generate subarrays in reverse order as well
    for (int i = 0; i < n; i++)
    {

        int sum1 = 0;

        for (int j = i; j < n; j++)
        {

            sum1 += arr[j];

            // Generate second non-overlapping subarray
            // on the left side
            for (int k = 0; k < i; k++)
            {

                int sum2 = 0;

                for (int l = k; l < i; l++)
                {

                    sum2 += arr[l];

                    // Update maximum absolute difference
                    res = max(res, abs(sum1 - sum2));
                }
            }
        }
    }

    return res;
}

int main()
{
    vector<int> arr = {2, -1, -2, 1, -4, 2, 8};

    cout << maxDiffSubArrays(arr);

    return 0;
}
Java
import java.util.Arrays;

public class GFG {
    int maxDiffSubArrays(int[] arr) {
        int n = arr.length;

        int res = Integer.MIN_VALUE;

        // Generate first subarray
        for (int i = 0; i < n; i++) {

            int sum1 = 0;

            for (int j = i; j < n; j++) {

                sum1 += arr[j];

                // Generate second non-overlapping subarray
                for (int k = j + 1; k < n; k++) {

                    int sum2 = 0;

                    for (int l = k; l < n; l++) {

                        sum2 += arr[l];

                        // Update maximum absolute difference
                        res = Math.max(res, Math.abs(sum1 - sum2));
                    }
                }
            }
        }

        // Generate subarrays in reverse order as well
        for (int i = 0; i < n; i++) {

            int sum1 = 0;

            for (int j = i; j < n; j++) {

                sum1 += arr[j];

                // Generate second non-overlapping subarray
                // on the left side
                for (int k = 0; k < i; k++) {

                    int sum2 = 0;

                    for (int l = k; l < i; l++) {

                        sum2 += arr[l];

                        // Update maximum absolute difference
                        res = Math.max(res, Math.abs(sum1 - sum2));
                    }
                }
            }
        }

        return res;
    }

    public static void main(String[] args) {
        GFG obj = new GFG();
        int[] arr = {2, -1, -2, 1, -4, 2, 8};
        System.out.println(obj.maxDiffSubArrays(arr));
    }
}
Python
def maxDiffSubArrays(arr):
    n = len(arr)

    res = float('-inf')

    # Generate first subarray
    for i in range(n):

        sum1 = 0

        for j in range(i, n):

            sum1 += arr[j]

            # Generate second non-overlapping subarray
            for k in range(j + 1, n):

                sum2 = 0

                for l in range(k, n):

                    sum2 += arr[l]

                    # Update maximum absolute difference
                    res = max(res, abs(sum1 - sum2))

    # Generate subarrays in reverse order as well
    for i in range(n):

        sum1 = 0

        for j in range(i, n):

            sum1 += arr[j]

            # Generate second non-overlapping subarray
            # on the left side
            for k in range(i):

                sum2 = 0

                for l in range(k, i):

                    sum2 += arr[l]

                    # Update maximum absolute difference
                    res = max(res, abs(sum1 - sum2))

    return res

if __name__ == '__main__':
    arr = [2, -1, -2, 1, -4, 2, 8]
    print(maxDiffSubArrays(arr))
C#
using System;

public class GFG
{
    public int maxDiffSubArrays(int[] arr)
    {
        int n = arr.Length;

        int res = int.MinValue;

        // Generate first subarray
        for (int i = 0; i < n; i++)
        {

            int sum1 = 0;

            for (int j = i; j < n; j++)
            {

                sum1 += arr[j];

                // Generate second non-overlapping subarray
                for (int k = j + 1; k < n; k++)
                {

                    int sum2 = 0;

                    for (int l = k; l < n; l++)
                    {

                        sum2 += arr[l];

                        // Update maximum absolute difference
                        res = Math.Max(res, Math.Abs(sum1 - sum2));
                    }
                }
            }
        }

        // Generate subarrays in reverse order as well
        for (int i = 0; i < n; i++)
        {

            int sum1 = 0;

            for (int j = i; j < n; j++)
            {

                sum1 += arr[j];

                // Generate second non-overlapping subarray
                // on the left side
                for (int k = 0; k < i; k++)
                {

                    int sum2 = 0;

                    for (int l = k; l < i; l++)
                    {

                        sum2 += arr[l];

                        // Update maximum absolute difference
                        res = Math.Max(res, Math.Abs(sum1 - sum2));
                    }
                }
            }
        }

        return res;
    }

    public static void Main()
    {
        GFG obj = new GFG();
        int[] arr = { 2, -1, -2, 1, -4, 2, 8 };
        Console.WriteLine(obj.maxDiffSubArrays(arr));
    }
}
JavaScript
function maxDiffSubArrays(arr) {
    let n = arr.length;

    let res = Number.MIN_SAFE_INTEGER;

    // Generate first subarray
    for (let i = 0; i < n; i++) {

        let sum1 = 0;

        for (let j = i; j < n; j++) {

            sum1 += arr[j];

            // Generate second non-overlapping subarray
            for (let k = j + 1; k < n; k++) {

                let sum2 = 0;

                for (let l = k; l < n; l++) {

                    sum2 += arr[l];

                    // Update maximum absolute difference
                    res = Math.max(res, Math.abs(sum1 - sum2));
                }
            }
        }
    }

    // Generate subarrays in reverse order as well
    for (let i = 0; i < n; i++) {

        let sum1 = 0;

        for (let j = i; j < n; j++) {

            sum1 += arr[j];

            // Generate second non-overlapping subarray
            // on the left side
            for (let k = 0; k < i; k++) {

                let sum2 = 0;

                for (let l = k; l < i; l++) {

                    sum2 += arr[l];

                    // Update maximum absolute difference
                    res = Math.max(res, Math.abs(sum1 - sum2));
                }
            }
        }
    }

    return res;
}

// Driver code
let arr = [2, -1, -2, 1, -4, 2, 8];
console.log(maxDiffSubArrays(arr));

Output
16

[Expected Approach] Kadane's Algorithm with Array Inversion - O(n) Time and O(n) Space

The idea is to partition the array at every position and maximize the difference between two non-overlapping subarrays. We use Kadane's algorithm to precompute maximum and minimum subarray sums on both sides of every partition, then evaluate both possible differences and take the maximum.

Let us understand with example:

  • For arr = [2, -1, -2, 1, -4, 2, 8], Kadane's algorithm builds leftMax = [2, 2, 2, 2, 2, 2, 10] and rightMax = [10, 10, 10, 10, 10, 10, 8].
  • After inverting the array and applying the same logic, we obtain leftMin = [2, -1, -3, -3, -6, -6, -6] and rightMin = [-6, -6, -6, -4, -4, 2, 8].
  • Consider the partition after index 4. The left part is [2, -1, -2, 1, -4] and the right part is [2, 8].
  • Here, leftMin[4] = -6 and rightMax[5] = 10, so the absolute difference becomes |-6 - 10| = 16.
  • No other partition gives a larger value, so the maximum absolute difference is 16.
C++
#include <iostream>
#include <vector>
using namespace std;

// Function to build maximum subarray sums from left to right
// leftMax[i] stores the maximum subarray sum in arr[0...i]
vector<int> buildLeftMax(vector<int> &arr)
{
    int n = arr.size();

    vector<int> leftMax(n);

    int curr = arr[0];
    int best = arr[0];

    leftMax[0] = best;

    for (int i = 1; i < n; i++)
    {

        // Apply Kadane's algorithm
        curr = max(arr[i], curr + arr[i]);

        // Update best maximum subarray sum seen so far
        best = max(best, curr);

        leftMax[i] = best;
    }

    return leftMax;
}

// Function to build maximum subarray sums from right to left
// rightMax[i] stores the maximum subarray sum in arr[i...n-1]
vector<int> buildRightMax(vector<int> &arr)
{
    int n = arr.size();

    vector<int> rightMax(n);

    int curr = arr[n - 1];
    int best = arr[n - 1];

    rightMax[n - 1] = best;

    for (int i = n - 2; i >= 0; i--)
    {

        // Apply Kadane's algorithm in reverse direction
        curr = max(arr[i], curr + arr[i]);

        // Update best maximum subarray sum seen so far
        best = max(best, curr);

        rightMax[i] = best;
    }

    return rightMax;
}

int maxDiffSubArrays(vector<int> &arr)
{
    int n = arr.size();

    // Maximum subarray sums on left and right side
    vector<int> leftMax = buildLeftMax(arr);
    vector<int> rightMax = buildRightMax(arr);

    // Create inverted array to obtain minimum subarray sums
    vector<int> inverted(arr);

    for (int &x : inverted)
        x = -x;

    // Maximum subarray on inverted array corresponds
    // to minimum subarray on original array
    vector<int> leftMin = buildLeftMax(inverted);
    vector<int> rightMin = buildRightMax(inverted);

    // Convert values back to minimum subarray sums
    for (int &x : leftMin)
        x = -x;

    for (int &x : rightMin)
        x = -x;

    int res = INT_MIN;

    // Try every possible partition point
    for (int i = 0; i < n - 1; i++)
    {

        // Maximum subarray on left and minimum subarray on right
        int option1 = abs(leftMax[i] - rightMin[i + 1]);

        // Minimum subarray on left and maximum subarray on right
        int option2 = abs(leftMin[i] - rightMax[i + 1]);

        // Update answer
        res = max(res, max(option1, option2));
    }

    return res;
}

int main()
{
    vector<int> arr = {2, -1, -2, 1, -4, 2, 8};

    cout << maxDiffSubArrays(arr);

    return 0;
}
Java
class GFG {

    // Function to build maximum subarray sums from left to
    // right. leftMax[i] stores the maximum subarray sum in
    // arr[0...i]
    static int[] buildLeftMax(int[] arr)
    {
        int n = arr.length;

        int[] leftMax = new int[n];

        int curr = arr[0];
        int best = arr[0];

        leftMax[0] = best;

        for (int i = 1; i < n; i++) {

            // Apply Kadane's algorithm
            curr = Math.max(arr[i], curr + arr[i]);

            // Update best maximum subarray sum seen so far
            best = Math.max(best, curr);

            leftMax[i] = best;
        }

        return leftMax;
    }

    // Function to build maximum subarray sums from right to
    // left. rightMax[i] stores the maximum subarray sum in
    // arr[i...n-1]
    static int[] buildRightMax(int[] arr)
    {
        int n = arr.length;

        int[] rightMax = new int[n];

        int curr = arr[n - 1];
        int best = arr[n - 1];

        rightMax[n - 1] = best;

        for (int i = n - 2; i >= 0; i--) {

            // Apply Kadane's algorithm in reverse
            // direction
            curr = Math.max(arr[i], curr + arr[i]);

            // Update best maximum subarray sum seen so far
            best = Math.max(best, curr);

            rightMax[i] = best;
        }

        return rightMax;
    }

    static int maxDiffSubArrays(int[] arr)
    {
        int n = arr.length;

        // Maximum subarray sums on left and right side
        int[] leftMax = buildLeftMax(arr);
        int[] rightMax = buildRightMax(arr);

        // Create inverted array to obtain minimum subarray
        // sums
        int[] inverted = arr.clone();

        for (int i = 0; i < n; i++)
            inverted[i] = -inverted[i];

        // Maximum subarray on inverted array corresponds
        // to minimum subarray on original array
        int[] leftMin = buildLeftMax(inverted);
        int[] rightMin = buildRightMax(inverted);

        // Convert values back to minimum subarray sums
        for (int i = 0; i < n; i++)
            leftMin[i] = -leftMin[i];

        for (int i = 0; i < n; i++)
            rightMin[i] = -rightMin[i];

        int res = Integer.MIN_VALUE;

        // Try every possible partition point
        for (int i = 0; i < n - 1; i++) {

            // Maximum subarray on left and minimum subarray
            // on right
            int option1
                = Math.abs(leftMax[i] - rightMin[i + 1]);

            // Minimum subarray on left and maximum subarray
            // on right
            int option2
                = Math.abs(leftMin[i] - rightMax[i + 1]);

            // Update answer
            res = Math.max(res, Math.max(option1, option2));
        }

        return res;
    }

    public static void main(String[] args)
    {
        int[] arr = { 2, -1, -2, 1, -4, 2, 8 };

        System.out.println(maxDiffSubArrays(arr));
    }
}
Python
import sys

# Function to build maximum subarray sums from left to right
# leftMax[i] stores the maximum subarray sum in arr[0...i]


def buildLeftMax(arr):
    n = len(arr)

    leftMax = [0] * n

    curr = arr[0]
    best = arr[0]

    leftMax[0] = best

    for i in range(1, n):
        # Apply Kadane's algorithm
        curr = max(arr[i], curr + arr[i])

        # Update best maximum subarray sum seen so far
        best = max(best, curr)

        leftMax[i] = best

    return leftMax

# Function to build maximum subarray sums from right to left
# rightMax[i] stores the maximum subarray sum in arr[i...n-1]


def buildRightMax(arr):
    n = len(arr)

    rightMax = [0] * n

    curr = arr[n - 1]
    best = arr[n - 1]

    rightMax[n - 1] = best

    for i in range(n - 2, -1, -1):
        # Apply Kadane's algorithm in reverse direction
        curr = max(arr[i], curr + arr[i])

        # Update best maximum subarray sum seen so far
        best = max(best, curr)

        rightMax[i] = best

    return rightMax


def maxDiffSubArrays(arr):
    n = len(arr)

    # Maximum subarray sums on left and right side
    leftMax = buildLeftMax(arr)
    rightMax = buildRightMax(arr)

    # Create inverted array to obtain minimum subarray sums
    inverted = [-x for x in arr]

    # Maximum subarray on inverted array corresponds
    # to minimum subarray on original array
    leftMin = buildLeftMax(inverted)
    rightMin = buildRightMax(inverted)

    # Convert values back to minimum subarray sums
    leftMin = [-x for x in leftMin]
    rightMin = [-x for x in rightMin]

    res = -sys.maxsize

    # Try every possible partition point
    for i in range(n - 1):
        # Maximum subarray on left and minimum subarray on right
        option1 = abs(leftMax[i] - rightMin[i + 1])

        # Minimum subarray on left and maximum subarray on right
        option2 = abs(leftMin[i] - rightMax[i + 1])

        # Update answer
        res = max(res, max(option1, option2))

    return res


if __name__ == '__main__':
    arr = [2, -1, -2, 1, -4, 2, 8]

    print(maxDiffSubArrays(arr))
C#
using System;

class GFG {
    // Function to build maximum subarray sums from left to
    // right. leftMax[i] stores the maximum subarray sum in
    // arr[0...i]
    static int[] buildLeftMax(int[] arr)
    {
        int n = arr.Length;

        int[] leftMax = new int[n];

        int curr = arr[0];
        int best = arr[0];

        leftMax[0] = best;

        for (int i = 1; i < n; i++) {
            // Apply Kadane's algorithm
            curr = Math.Max(arr[i], curr + arr[i]);

            // Update best maximum subarray sum seen so far
            best = Math.Max(best, curr);

            leftMax[i] = best;
        }

        return leftMax;
    }

    // Function to build maximum subarray sums from right to
    // left. rightMax[i] stores the maximum subarray sum in
    // arr[i...n-1]
    static int[] buildRightMax(int[] arr)
    {
        int n = arr.Length;

        int[] rightMax = new int[n];

        int curr = arr[n - 1];
        int best = arr[n - 1];

        rightMax[n - 1] = best;

        for (int i = n - 2; i >= 0; i--) {
            // Apply Kadane's algorithm in reverse
            // direction
            curr = Math.Max(arr[i], curr + arr[i]);

            // Update best maximum subarray sum seen so far
            best = Math.Max(best, curr);

            rightMax[i] = best;
        }

        return rightMax;
    }

    static int maxDiffSubArrays(int[] arr)
    {
        int n = arr.Length;

        // Maximum subarray sums on left and right side
        int[] leftMax = buildLeftMax(arr);
        int[] rightMax = buildRightMax(arr);

        // Create inverted array to obtain minimum subarray
        // sums
        int[] inverted = (int[])arr.Clone();

        for (int i = 0; i < n; i++)
            inverted[i] = -inverted[i];

        // Maximum subarray on inverted array corresponds
        // to minimum subarray on original array
        int[] leftMin = buildLeftMax(inverted);
        int[] rightMin = buildRightMax(inverted);

        // Convert values back to minimum subarray sums
        for (int i = 0; i < n; i++)
            leftMin[i] = -leftMin[i];

        for (int i = 0; i < n; i++)
            rightMin[i] = -rightMin[i];

        int res = int.MinValue;

        // Try every possible partition point
        for (int i = 0; i < n - 1; i++) {
            // Maximum subarray on left and minimum subarray
            // on right
            int option1
                = Math.Abs(leftMax[i] - rightMin[i + 1]);

            // Minimum subarray on left and maximum subarray
            // on right
            int option2
                = Math.Abs(leftMin[i] - rightMax[i + 1]);

            // Update answer
            res = Math.Max(res, Math.Max(option1, option2));
        }

        return res;
    }

    static void Main()
    {
        int[] arr = { 2, -1, -2, 1, -4, 2, 8 };

        Console.WriteLine(maxDiffSubArrays(arr));
    }
}
JavaScript
// Function to build maximum subarray sums from left to
// right. leftMax[i] stores the maximum subarray sum in
// arr[0...i]
function buildLeftMax(arr)
{
    const n = arr.length;

    const leftMax = new Array(n);

    let curr = arr[0];
    let best = arr[0];

    leftMax[0] = best;

    for (let i = 1; i < n; i++) {

        // Apply Kadane's algorithm
        curr = Math.max(arr[i], curr + arr[i]);

        // Update best maximum subarray sum seen so far
        best = Math.max(best, curr);

        leftMax[i] = best;
    }

    return leftMax;
}

// Function to build maximum subarray sums from right to
// left. rightMax[i] stores the maximum subarray sum in
// arr[i...n-1]
function buildRightMax(arr)
{
    const n = arr.length;

    const rightMax = new Array(n);

    let curr = arr[n - 1];
    let best = arr[n - 1];

    rightMax[n - 1] = best;

    for (let i = n - 2; i >= 0; i--) {

        // Apply Kadane's algorithm in reverse direction
        curr = Math.max(arr[i], curr + arr[i]);

        // Update best maximum subarray sum seen so far
        best = Math.max(best, curr);

        rightMax[i] = best;
    }

    return rightMax;
}

function maxDiffSubArrays(arr)
{
    const n = arr.length;

    // Maximum subarray sums on left and right side
    const leftMax = buildLeftMax(arr);
    const rightMax = buildRightMax(arr);

    // Create inverted array to obtain minimum subarray
    // sums.
    const inverted = arr.map(x => -x);

    // Maximum subarray on inverted array corresponds
    // to minimum subarray on original array
    const leftMin = buildLeftMax(inverted);
    const rightMin = buildRightMax(inverted);

    // Convert values back to minimum subarray sums
    const leftMinConverted = leftMin.map(x => -x);
    const rightMinConverted = rightMin.map(x => -x);

    let res = Number.MIN_SAFE_INTEGER;

    // Try every possible partition point
    for (let i = 0; i < n - 1; i++) {

        // Maximum subarray on left and minimum subarray on
        // right
        const option1 = Math.abs(
            leftMax[i] - rightMinConverted[i + 1]);

        // Minimum subarray on left and maximum subarray on
        // right
        const option2 = Math.abs(leftMinConverted[i]
                                 - rightMax[i + 1]);

        // Update answer
        res = Math.max(res, Math.max(option1, option2));
    }

    return res;
}

// Driver Code
const arr = [ 2, -1, -2, 1, -4, 2, 8 ];
console.log(maxDiffSubArrays(arr));

Output
16
Comment