# Maximum Sum SubArray using Divide and Conquer | Set 2

• Difficulty Level : Hard
• Last Updated : 10 Nov, 2021

Given an array arr[] of integers, the task is to find the maximum sum sub-array among all the possible sub-arrays.
Examples:

Input: arr[] = {-2, 1, -3, 4, -1, 2, 1, -5, 4}
Output:
{4, -1, 2, 1} is the required sub-array.
Input: arr[] = {2, 2, -2}
Output:

Approach: Till now we are only aware of Kadane’s Algorithm which solves this problem in O(n) using dynamic programming.
We had also discussed a divide and conquer approach for maximum sum subarray in O(N*logN) time complexity.
The following approach solves it using Divide and Conquer approach which takes the same time complexity of O(n).
Divide and conquer algorithms generally involves dividing the problem into sub-problems and conquering them separately. For this problem we maintain a structure (in cpp) or class(in java or python) which stores the following values:

1. Total sum for a sub-array.
2. Maximum prefix sum for a sub-array.
3. Maximum suffix sum for a sub-array.
4. Overall maximum sum for a sub-array.(This contains the max sum for a sub-array).

During the recursion(Divide part) the array is divided into 2 parts from the middle. The left node structure contains all the above values for the left part of array and the right node structure contains all the above values. Having both the nodes, now we can merge the two nodes by computing all the values for resulting node.
The max prefix sum for the resulting node will be maximum value among the maximum prefix sum of left node or left node sum + max prefix sum of right node or total sum of both the nodes (which is possible for an array with all positive values).
Similarly the max suffix sum for the resulting node will be maximum value among the maximum suffix sum of right node or right node sum + max suffix sum of left node or total sum of both the nodes (which is again possible for an array with all positive values).
The total sum for the resulting node is the sum of both left node and right node sum.
Now, the max subarray sum for the resulting node will be maximum among prefix sum of resulting node, suffix sum of resulting node, total sum of resulting node, maximum sum of left node, maximum sum of right node, sum of maximum suffix sum of left node and maximum prefix sum of right node.
Here the conquer part can be done in O(1) time by combining the result from the left and right node structures.
Below is the implementation of the above approach:

## C++

 `// C++ implementation of the approach``#include``using` `namespace` `std;` `struct` `Node {``    ` `    ``// To store the maximum sum``    ``// for a sub-array``    ``long` `long` `_max;``    ` `    ``// To store the maximum prefix``    ``// sum for a sub-array``    ``long` `long` `_pre;``    ` `    ``// To store the maximum suffix``    ``// sum for a sub-array``    ``long` `long` `_suf;``    ` `    ``// To store the total sum``    ``// for a sub-array``    ``long` `long` `_sum;` `};`  `// Function to create a node``Node getNode(``long` `long` `x){``    ``Node a;``    ``a._max = x;``    ``a._pre = x;``    ``a._suf = x;``    ``a._sum = x;``    ``return` `a;``}` `// Function to merge the 2 nodes left and right``Node merg(``const` `Node &l, ``const` `Node &r){``    ` `    ``// Creating node ans``    ``Node ans ;` `    ``// Initializing all the variables:``    ``ans._max = ans._pre = ans._suf = ans._sum = 0;``    ` `    ``// The max prefix sum of ans Node is maximum of``    ``// a) max prefix sum of left Node``    ``// b) sum of left Node + max prefix sum of right Node``    ``// c) sum of left Node + sum of right Node``    ``ans._pre = max({l._pre, l._sum+r._pre, l._sum+r._sum});` `    ``// The max suffix sum of ans Node is maximum of``    ``// a) max suffix sum of right Node``    ``// b) sum of right Node + max suffix sum of left Node``    ``// c) sum of left Node + sum of right Node``    ``ans._suf = max({r._suf, r._sum+l._suf, l._sum+r._sum});``    ` `    ``// Total sum of ans Node = total sum of left Node + total sum of right Node``    ``ans._sum = l._sum + r._sum;``    ` `    ``// The max sum of ans Node stores the answer which is the maximum value among:``    ``// prefix sum of ans Node``    ``// suffix sum of ans Node``    ``// maximum value of left Node``    ``// maximum value of right Node``    ``// prefix value of right Node + suffix value of left Node``    ``ans._max = max({ans._pre, ans._suf, ans._sum,l._max, r._max, l._suf+r._pre});` `    ``// Return the ans Node``    ``return` `ans;``}` `// Function for calculating the``// max_sum_subArray using divide and conquer``Node getMaxSumSubArray(``int` `l, ``int` `r, vector<``long` `long``> &ar){` `    ``if` `(l == r) ``return` `getNode(ar[l]);` `    ``int` `mid = (l + r) >> 1;``    ` `    ``// Call method to return left Node:``    ``Node left = getMaxSumSubArray(l, mid, ar);``    ` `    ``// Call method to return right Node:``    ``Node right = getMaxSumSubArray(mid+1, r, ar);``    ` `    ``// Return the merged Node:``    ``return` `merg(left, right);` `}` `// Driver code``int` `main(){` `    ``vector<``long` `long``> ar = {-2, -5, 6, -2, -3, 1, 5, -6};``    ``int` `n = ar.size();``    ``Node ans = getMaxSumSubArray(0, n-1, ar);``    ``cout << ``"Answer is "` `<< ans._max << ``"\n"``;` `    ``return` `0;``}`

## Java

 `// Java implementation of the approach``import` `java.util.*;``class` `GFG``{``static` `class` `Node``{``    ` `    ``// To store the maximum sum``    ``// for a sub-array``    ``int` `_max;``    ` `    ``// To store the maximum prefix``    ``// sum for a sub-array``    ``int` `_pre;``    ` `    ``// To store the maximum suffix``    ``// sum for a sub-array``    ``int` `_suf;``    ` `    ``// To store the total sum``    ``// for a sub-array``    ``int` `_sum;` `};`  `// Function to create a node``static` `Node getNode(``int` `x)``{``    ``Node a = ``new` `Node();``    ``a._max = x;``    ``a._pre = x;``    ``a._suf = x;``    ``a._sum = x;``    ``return` `a;``}` `// Function to merge the 2 nodes left and right``static` `Node merg(Node l, Node r)``{``    ` `    ``// Creating node ans``    ``Node ans = ``new` `Node();` `    ``// Initializing all the variables:``    ``ans._max = ans._pre = ans._suf = ans._sum = ``0``;``    ` `    ``// The max prefix sum of ans Node is maximum of``    ``// a) max prefix sum of left Node``    ``// b) sum of left Node + max prefix sum of right Node``    ``// c) sum of left Node + sum of right Node``    ``ans._pre = Arrays.stream(``new` `int``[]{l._pre, l._sum+r._pre,``                                       ``l._sum+r._sum}).max().getAsInt();` `    ``// The max suffix sum of ans Node is maximum of``    ``// a) max suffix sum of right Node``    ``// b) sum of right Node + max suffix sum of left Node``    ``// c) sum of left Node + sum of right Node``    ``ans._suf = Arrays.stream(``new` `int``[]{r._suf, r._sum+l._suf,``                                       ``l._sum+r._sum}).max().getAsInt();``    ` `    ``// Total sum of ans Node = total sum of``  ``// left Node + total sum of right Node``    ``ans._sum = l._sum + r._sum;``    ` `    ``// The max sum of ans Node stores``    ``// the answer which is the maximum value among:``    ``// prefix sum of ans Node``    ``// suffix sum of ans Node``    ``// maximum value of left Node``    ``// maximum value of right Node``    ``// prefix value of right Node + suffix value of left Node``    ``ans._max = Arrays.stream(``new` `int``[]{ans._pre,``                                       ``ans._suf,``                                       ``ans._sum,``                                       ``l._max, r._max,``                                       ``l._suf+r._pre}).max().getAsInt();` `    ``// Return the ans Node``    ``return` `ans;``}` `// Function for calculating the``// max_sum_subArray using divide and conquer``static` `Node getMaxSumSubArray(``int` `l, ``int` `r, ``int` `[]ar)``{` `    ``if` `(l == r) ``return` `getNode(ar[l]);``    ``int` `mid = (l + r) >> ``1``;``    ` `    ``// Call method to return left Node:``    ``Node left = getMaxSumSubArray(l, mid, ar);``    ` `    ``// Call method to return right Node:``    ``Node right = getMaxSumSubArray(mid + ``1``, r, ar);``    ` `    ``// Return the merged Node:``    ``return` `merg(left, right);` `}` `// Driver code``public` `static` `void` `main(String[] args)``{``    ``int` `[]ar = {-``2``, -``5``, ``6``, -``2``, -``3``, ``1``, ``5``, -``6``};``    ``int` `n = ar.length;``    ``Node ans = getMaxSumSubArray(``0``, n - ``1``, ar);``    ``System.out.print(``"Answer is "` `+  ans._max + ``"\n"``);``}``}` `// This code is contributed by shikhasingrajput`

## Python3

 `# Python3 implementation of the approach` `class` `Node:``    ` `    ``def` `__init__(``self``, x):``        ` `        ``# To store the maximum sum for a sub-array``        ``self``._max ``=` `x``        ` `        ``# To store the maximum prefix sum for a sub-array``        ``self``._pre ``=` `x``        ` `        ``# To store the maximum suffix sum for a sub-array``        ``self``._suf ``=` `x``        ` `        ``# To store the total sum for a sub-array``        ``self``._sum ``=` `x``        ` `# Function to merge the 2 nodes left and right``def` `merg(l, r):``    ` `    ``# Creating node ans``    ``ans ``=` `Node(``0``)` `    ``# The max prefix sum of ans Node is maximum of``    ``# a) max prefix sum of left Node``    ``# b) sum of left Node + max prefix sum of right Node``    ``# c) sum of left Node + sum of right Node``    ``ans._pre ``=` `max``(l._pre, l._sum``+``r._pre, l._sum``+``r._sum)` `    ``# The max suffix sum of ans Node is maximum of``    ``# a) max suffix sum of right Node``    ``# b) sum of right Node + max suffix sum of left Node``    ``# c) sum of left Node + sum of right Node``    ``ans._suf ``=` `max``(r._suf, r._sum``+``l._suf, l._sum``+``r._sum)``    ` `    ``# Total sum of ans Node = total sum of``    ``# left Node + total sum of right Node``    ``ans._sum ``=` `l._sum ``+` `r._sum``    ` `    ``# The max sum of ans Node stores the answer``    ``# which is the maximum value among:``    ``# prefix sum of ans Node``    ``# suffix sum of ans Node``    ``# maximum value of left Node``    ``# maximum value of right Node``    ``# prefix value of left Node + suffix value of right Node``    ``ans._max ``=` `max``(ans._pre, ans._suf, ans._sum,``                    ``l._max, r._max, l._suf``+``r._pre)` `    ``# Return the ans Node``    ``return` `ans` `# Function for calculating the``# max_sum_subArray using divide and conquer``def` `getMaxSumSubArray(l, r, ar):` `    ``if` `l ``=``=` `r: ``return` `Node(ar[l])` `    ``mid ``=` `(l ``+` `r) ``/``/` `2``    ` `    ``# Call method to return left Node:``    ``left ``=` `getMaxSumSubArray(l, mid, ar)``    ` `    ``# Call method to return right Node:``    ``right ``=` `getMaxSumSubArray(mid``+``1``, r, ar)``    ` `    ``# Return the merged Node:``    ``return` `merg(left, right)` `# Driver code``if` `__name__ ``=``=` `"__main__"``:` `    ``ar ``=` `[``-``2``, ``-``5``, ``6``, ``-``2``, ``-``3``, ``1``, ``5``, ``-``6``]``    ``n ``=` `len``(ar)``    ``ans ``=` `getMaxSumSubArray(``0``, n``-``1``, ar)``    ``print``(``"Answer is"``, ans._max)` `# This code is contributed by Rituraj Jain`

## C#

 `// C# implementation of the approach``using` `System;``using` `System.Linq;``public` `class` `GFG``{``  ` `class` `Node``{``    ` `    ``// To store the maximum sum``    ``// for a sub-array``    ``public` `int` `_max;``    ` `    ``// To store the maximum prefix``    ``// sum for a sub-array``    ``public` `int` `_pre;``    ` `    ``// To store the maximum suffix``    ``// sum for a sub-array``    ``public` `int` `_suf;``    ` `    ``// To store the total sum``    ``// for a sub-array``    ``public` `int` `_sum;``};` `// Function to create a node``static` `Node getNode(``int` `x)``{``    ``Node a = ``new` `Node();``    ``a._max = x;``    ``a._pre = x;``    ``a._suf = x;``    ``a._sum = x;``    ``return` `a;``}` `// Function to merge the 2 nodes left and right``static` `Node merg(Node l, Node r)``{``    ` `    ``// Creating node ans``    ``Node ans = ``new` `Node();` `    ``// Initializing all the variables:``    ``ans._max = ans._pre = ans._suf = ans._sum = 0;``    ` `    ``// The max prefix sum of ans Node is maximum of``    ``// a) max prefix sum of left Node``    ``// b) sum of left Node + max prefix sum of right Node``    ``// c) sum of left Node + sum of right Node``    ``ans._pre = (``new` `int``[]{l._pre, l._sum+r._pre,``                                       ``l._sum+r._sum}).Max();` `    ``// The max suffix sum of ans Node is maximum of``    ``// a) max suffix sum of right Node``    ``// b) sum of right Node + max suffix sum of left Node``    ``// c) sum of left Node + sum of right Node``    ``ans._suf = (``new` `int``[]{r._suf, r._sum+l._suf,``                                       ``l._sum+r._sum}).Max();``    ` `    ``// Total sum of ans Node = total sum of``  ``// left Node + total sum of right Node``    ``ans._sum = l._sum + r._sum;``    ` `    ``// The max sum of ans Node stores``    ``// the answer which is the maximum value among:``    ``// prefix sum of ans Node``    ``// suffix sum of ans Node``    ``// maximum value of left Node``    ``// maximum value of right Node``    ``// prefix value of right Node + suffix value of left Node``    ``ans._max = (``new` `int``[]{ans._pre,``                                       ``ans._suf,``                                       ``ans._sum,``                                       ``l._max, r._max,``                                       ``l._suf+r._pre}).Max();` `    ``// Return the ans Node``    ``return` `ans;``}` `// Function for calculating the``// max_sum_subArray using divide and conquer``static` `Node getMaxSumSubArray(``int` `l, ``int` `r, ``int` `[]ar)``{``    ``if` `(l == r) ``return` `getNode(ar[l]);``    ``int` `mid = (l + r) >> 1;``    ` `    ``// Call method to return left Node:``    ``Node left = getMaxSumSubArray(l, mid, ar);``    ` `    ``// Call method to return right Node:``    ``Node right = getMaxSumSubArray(mid + 1, r, ar);``    ` `    ``// Return the merged Node:``    ``return` `merg(left, right);``}` `// Driver code``public` `static` `void` `Main(String[] args)``{``    ``int` `[]ar = {-2, -5, 6, -2, -3, 1, 5, -6};``    ``int` `n = ar.Length;``    ``Node ans = getMaxSumSubArray(0, n - 1, ar);``    ``Console.Write(``"Answer is "` `+  ans._max + ``"\n"``);``}``}` `// This code is contributed by shikhasingrajput`

## Javascript

 ``

Output:

`Answer is 7`

Time Complexity: The getMaxSumSubArray() recursive function generates the following recurrence relation.
T(n) = 2 * T(n / 2) + O(1) note that conquer part takes only O(1) time. So on solving this recurrence using Master’s Theorem we get the time complexity of O(n).

My Personal Notes arrow_drop_up