Maximum Subarray Sum using Divide and Conquer algorithm

21 Jun, 2022
You are given a one dimensional array that may contain both positive and negative integers, find the sum of contiguous subarray of numbers which has the largest sum.
For example, if the given array is {-2, -5, 6, -2, -3, 1, 5, -6}, then the maximum subarray sum is 7 (see highlighted elements).
Chapters
descriptions off, selected
captions settings, opens captions settings dialog
captions off, selected
English
This is a modal window.
Beginning of dialog window. Escape will cancel and close the window.
End of dialog window.
The naive method is to run two loops. The outer loop picks the beginning element, the inner loop finds the maximum possible sum with first element picked by outer loop and compares this maximum with the overall maximum. Finally, return the overall maximum. The time complexity of the Naive method is O(n^2).
Using Divide and Conquer approach, we can find the maximum subarray sum in O(nLogn) time. Following is the Divide and Conquer algorithm. 
Divide the given array in two halvesReturn the maximum of following threeMaximum subarray sum in left half (Make a recursive call)Maximum subarray sum in right half (Make a recursive call)Maximum subarray sum such that the subarray crosses the midpoint
Divide the given array in two halves
Return the maximum of following threeMaximum subarray sum in left half (Make a recursive call)Maximum subarray sum in right half (Make a recursive call)Maximum subarray sum such that the subarray crosses the midpoint
Maximum subarray sum in left half (Make a recursive call)
Maximum subarray sum in right half (Make a recursive call)
Maximum subarray sum such that the subarray crosses the midpoint
The lines 2.a and 2.b are simple recursive calls. How to find maximum subarray sum such that the subarray crosses the midpoint? We can easily find the crossing sum in linear time. The idea is simple, find the maximum sum starting from mid point and ending at some point on left of mid, then find the maximum sum starting from mid + 1 and ending with some point on right of mid + 1. Finally, combine the two and return the maximum among left, right and combination of both.
Below is the implementation of the above approach: 
C++
Java
Python
C#
PHP
Javascript
// A Divide and Conquer based program for maximum subarray// sum problem#include <limits.h>#include <stdio.h>  // A utility function to find maximum of two integersint max(int a, int b) { return (a > b) ? a : b; }  // A utility function to find maximum of three integersint max(int a, int b, int c) { return max(max(a, b), c); }  // Find the maximum possible sum in arr[] such that arr[m]// is part of itint maxCrossingSum(int arr[], int l, int m, int h){    // Include elements on left of mid.    int sum = 0;    int left_sum = INT_MIN;    for (int i = m; i >= l; i--) {        sum = sum + arr[i];        if (sum > left_sum)            left_sum = sum;    }      // Include elements on right of mid    sum = 0;    int right_sum = INT_MIN;    for (int i = m + 1; i <= h; i++) {        sum = sum + arr[i];        if (sum > right_sum)            right_sum = sum;    }      // Return sum of elements on left and right of mid    // returning only left_sum + right_sum will fail for    // [-2, 1]    return max(left_sum + right_sum, left_sum, right_sum);}  // Returns sum of maximum sum subarray in aa[l..h]int maxSubArraySum(int arr[], int l, int h){    // Base Case: Only one element    if (l == h)        return arr[l];      // Find middle point    int m = (l + h) / 2;      /* Return maximum of following three possible cases            a) Maximum subarray sum in left half            b) Maximum subarray sum in right half            c) Maximum subarray sum such that the subarray       crosses the midpoint */    return max(maxSubArraySum(arr, l, m),               maxSubArraySum(arr, m + 1, h),               maxCrossingSum(arr, l, m, h));}  /*Driver program to test maxSubArraySum*/int main(){    int arr[] = { 2, 3, 4, 5, 7 };    int n = sizeof(arr) / sizeof(arr[0]);    int max_sum = maxSubArraySum(arr, 0, n - 1);    printf("Maximum contiguous sum is %d\n", max_sum);    getchar();    return 0;}
// A Divide and Conquer based Java// program for maximum subarray sum// problemimport java.util.*;  class GFG {      // Find the maximum possible sum in arr[]    // such that arr[m] is part of it    static int maxCrossingSum(int arr[], int l, int m,                              int h)    {        // Include elements on left of mid.        int sum = 0;        int left_sum = Integer.MIN_VALUE;        for (int i = m; i >= l; i--) {            sum = sum + arr[i];            if (sum > left_sum)                left_sum = sum;        }          // Include elements on right of mid        sum = 0;        int right_sum = Integer.MIN_VALUE;        for (int i = m + 1; i <= h; i++) {            sum = sum + arr[i];            if (sum > right_sum)                right_sum = sum;        }          // Return sum of elements on left        // and right of mid        // returning only left_sum + right_sum will fail for        // [-2, 1]        return Math.max(left_sum + right_sum,                        Math.max(left_sum, right_sum));    }      // Returns sum of maximum sum subarray    // in aa[l..h]    static int maxSubArraySum(int arr[], int l, int h)    {        // Base Case: Only one element        if (l == h)            return arr[l];          // Find middle point        int m = (l + h) / 2;          /* Return maximum of following three        possible cases:        a) Maximum subarray sum in left half        b) Maximum subarray sum in right half        c) Maximum subarray sum such that the        subarray crosses the midpoint */        return Math.max(            Math.max(maxSubArraySum(arr, l, m),                     maxSubArraySum(arr, m + 1, h)),            maxCrossingSum(arr, l, m, h));    }      /* Driver program to test maxSubArraySum */    public static void main(String[] args)    {        int arr[] = { 2, 3, 4, 5, 7 };        int n = arr.length;        int max_sum = maxSubArraySum(arr, 0, n - 1);          System.out.println("Maximum contiguous sum is "                           + max_sum);    }}// This code is contributed by Prerna Saini
# A Divide and Conquer based program# for maximum subarray sum problem  # Find the maximum possible sum in# arr[] auch that arr[m] is part of it    def maxCrossingSum(arr, l, m, h):      # Include elements on left of mid.    sm = 0    left_sum = -10000      for i in range(m, l-1, -1):        sm = sm + arr[i]          if (sm > left_sum):            left_sum = sm      # Include elements on right of mid    sm = 0    right_sum = -1000    for i in range(m + 1, h + 1):        sm = sm + arr[i]          if (sm > right_sum):            right_sum = sm      # Return sum of elements on left and right of mid    # returning only left_sum + right_sum will fail for [-2, 1]    return max(left_sum + right_sum, left_sum, right_sum)    # Returns sum of maximum sum subarray in aa[l..h]def maxSubArraySum(arr, l, h):      # Base Case: Only one element    if (l == h):        return arr[l]      # Find middle point    m = (l + h) // 2      # Return maximum of following three possible cases    # a) Maximum subarray sum in left half    # b) Maximum subarray sum in right half    # c) Maximum subarray sum such that the    #     subarray crosses the midpoint    return max(maxSubArraySum(arr, l, m),               maxSubArraySum(arr, m+1, h),               maxCrossingSum(arr, l, m, h))    # Driver Codearr = [2, 3, 4, 5, 7]n = len(arr)  max_sum = maxSubArraySum(arr, 0, n-1)print("Maximum contiguous sum is ", max_sum)  # This code is contributed by Nikita Tiwari.
// A Divide and Conquer based C#// program for maximum subarray sum// problemusing System;  class GFG {      // Find the maximum possible sum in arr[]    // such that arr[m] is part of it    static int maxCrossingSum(int[] arr, int l, int m,                              int h)    {        // Include elements on left of mid.        int sum = 0;        int left_sum = int.MinValue;        for (int i = m; i >= l; i--) {            sum = sum + arr[i];            if (sum > left_sum)                left_sum = sum;        }          // Include elements on right of mid        sum = 0;        int right_sum = int.MinValue;        ;        for (int i = m + 1; i <= h; i++) {            sum = sum + arr[i];            if (sum > right_sum)                right_sum = sum;        }          // Return sum of elements on left        // and right of mid        // returning only left_sum + right_sum will fail for        // [-2, 1]        return Math.Max(left_sum + right_sum,                        Math.Max(left_sum, right_sum));    }      // Returns sum of maximum sum subarray    // in aa[l..h]    static int maxSubArraySum(int[] arr, int l, int h)    {          // Base Case: Only one element        if (l == h)            return arr[l];          // Find middle point        int m = (l + h) / 2;          /* Return maximum of following three        possible cases:        a) Maximum subarray sum in left half        b) Maximum subarray sum in right half        c) Maximum subarray sum such that the        subarray crosses the midpoint */        return Math.Max(            Math.Max(maxSubArraySum(arr, l, m),                     maxSubArraySum(arr, m + 1, h)),            maxCrossingSum(arr, l, m, h));    }      /* Driver program to test maxSubArraySum */    public static void Main()    {        int[] arr = { 2, 3, 4, 5, 7 };        int n = arr.Length;        int max_sum = maxSubArraySum(arr, 0, n - 1);          Console.Write("Maximum contiguous sum is "                      + max_sum);    }}  // This code is contributed by vt_m.
<?php // A Divide and Conquer based program // for maximum subarray sum problem   // Find the maximum possible sum in arr[] // such that arr[m] is part of it function maxCrossingSum(&$arr, $l, $m, $h) {     // Include elements on left of mid.     $sum = 0;     $left_sum = PHP_INT_MIN;     for ($i = $m; $i >= $l; $i--)     {         $sum = $sum + $arr[$i];         if ($sum > $left_sum)         $left_sum = $sum;     }       // Include elements on right of mid     $sum = 0;     $right_sum = PHP_INT_MIN;     for ($i = $m + 1; $i <= $h; $i++)     {         $sum = $sum + $arr[$i];         if ($sum > $right_sum)         $right_sum = $sum;     }       // Return sum of elements on left     // and right of mid     // returning only left_sum + right_sum will fail for [-2, 1]     return max($left_sum + $right_sum, $left_sum, $right_sum); }   // Returns sum of maximum sum // subarray in aa[l..h] function maxSubArraySum(&$arr, $l, $h) {     // Base Case: Only one element     if ($l == $h)         return $arr[$l];           // Find middle point     $m = intval(($l + $h) / 2);           /* Return maximum of following three possible cases         a) Maximum subarray sum in left half         b) Maximum subarray sum in right half         c) Maximum subarray sum such that the         subarray crosses the midpoint */    return max(maxSubArraySum($arr, $l, $m),             maxSubArraySum($arr, $m + 1, $h),             maxCrossingSum($arr, $l, $m, $h)); }   // Driver Code $arr = array(2, 3, 4, 5, 7); $n = count($arr); $max_sum = maxSubArraySum($arr, 0, $n - 1); echo "Maximum contiguous sum is " . $max_sum;   // This code is contributed by rathbhupendra, Aadil ?> 
<script>    // A Divide and Conquer based program for maximum subarray    // sum problem      // A utility function to find maximum of two integers    function max(a,b) { return (a > b) ? a : b; }      // A utility function to find maximum of three integers    function max(a,b,c) { return Math.max(Math.max(a, b), c); }      // Find the maximum possible sum in arr[] auch that arr[m]    // is part of it    function maxCrossingSum(arr, l, m,h)    {        // Include elements on left of mid.        let sum = 0;        let left_sum = Number.MIN_VALUE;        for (let i = m; i >= l; i--) {            sum = sum + arr[i];            if (sum > left_sum)                left_sum = sum;        }          // Include elements on right of mid        sum = 0;        let right_sum = Number.MIN_VALUE;        for (let i = m + 1; i <= h; i++) {            sum = sum + arr[i];            if (sum > right_sum)                right_sum = sum;        }          // Return sum of elements on left and right of mid        // returning only left_sum + right_sum will fail for        // [-2, 1]        return max(left_sum + right_sum, left_sum, right_sum);    }      // Returns sum of maximum sum subarray in aa[l..h]    function maxSubArraySum(arr, l,h)    {        // Base Case: Only one element        if (l == h)            return arr[l];          // Find middle point        let m = parseInt((l + h) / 2, 10);          /* Return maximum of following three possible cases                a) Maximum subarray sum in left half                b) Maximum subarray sum in right half                c) Maximum subarray sum such that the subarray        crosses the midpoint */        return max(maxSubArraySum(arr, l, m),                maxSubArraySum(arr, m + 1, h),                maxCrossingSum(arr, l, m, h));    }        let arr = [ 2, 3, 4, 5, 7 ];    let n = arr.length;    let max_sum = maxSubArraySum(arr, 0, n - 1);    document.write("Maximum contiguous sum is " + max_sum);        // This code is contributed by vaibhavrabadiya117.  </script>
Maximum contiguous sum is 21n
Time Complexity: maxSubArraySum() is a recursive method and time complexity can be expressed as following recurrence relation. T(n) = 2T(n/2) + Θ(n) 
Time Complexity : O(nlogn)
Auxiliary Space: O(1).The above recurrence is similar to Merge Sort and can be solved either using Recurrence Tree method or Master method. It falls in case II of Master Method and solution of the recurrence is Θ(nLogn). 
The Kadane’s Algorithm for this problem takes O(n) time. Therefore the Kadane’s algorithm is better than the Divide and Conquer approach, but this problem can be considered as a good example to show power of Divide and Conquer. The above simple approach where we divide the array in two halves, reduces the time complexity from O(n^2) to O(nLogn).
References: Introduction to Algorithms by Clifford Stein, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
rathbhupendra
MohammedAadil
mayanktyagi1709
vaibhavrabadiya117
ankitayan
surindertarika1234
gabaa406
dspartho1998
arpita4086
srm_
anandkumarshivam2266
resonance443731
Amazon
Junglee Games
subarray
subarray-sum
Arrays
Divide and Conquer
Dynamic Programming
Amazon
Junglee Games
Arrays
Dynamic Programming
Divide and Conquer
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.