Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • DSA
  • Interview Questions on Array
  • Practice Array
  • MCQs on Array
  • Tutorial on Array
  • Types of Arrays
  • Array Operations
  • Subarrays, Subsequences, Subsets
  • Reverse Array
  • Static Vs Arrays
  • Array Vs Linked List
  • Array | Range Queries
  • Advantages & Disadvantages
Open In App
Next Article:
Longest unique subarray of an Array with maximum sum in another Array
Next article icon

Maximum Sum SubArray using Divide and Conquer | Set 2

Last Updated : 10 Nov, 2021
Comments
Improve
Suggest changes
Like Article
Like
Report

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: 6 
{4, -1, 2, 1} is the required sub-array.
Input: arr[] = {2, 2, -2} 
Output: 4 
 

 

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<bits/stdc++.h>
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




<script>
 
// Javascript implementation of the approach
class Node {
 
    constructor()
    {
        // To store the maximum sum
        // for a sub-array
        var _max;
         
        // To store the maximum prefix
        // sum for a sub-array
        var _pre;
         
        // To store the maximum suffix
        // sum for a sub-array
        var _suf;
         
        // To store the total sum
        // for a sub-array
        var _sum;
    }
 
};
 
 
// Function to create a node
function getNode(x){
    var 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
function merg(l, r){
     
    // Creating node ans
    var 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 = Math.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 = Math.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 = Math.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
function getMaxSumSubArray(l, r, ar){
 
    if (l == r) return getNode(ar[l]);
 
    var mid = (l + r) >> 1;
     
    // Call method to return left Node:
    var left = getMaxSumSubArray(l, mid, ar);
     
    // Call method to return right Node:
    var right = getMaxSumSubArray(mid+1, r, ar);
     
    // Return the merged Node:
    return merg(left, right);
 
}
 
// Driver code
var ar = [-2, -5, 6, -2, -3, 1, 5, -6];
var n = ar.length;
var ans = getMaxSumSubArray(0, n-1, ar);
document.write("Answer is " + ans._max + "<br>");
 
// This code is contributed by rutvik_56.
</script>
 
 

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).
 



Next Article
Longest unique subarray of an Array with maximum sum in another Array

A

Abhimanyu_97
Improve
Article Tags :
  • Arrays
  • C++ Programs
  • Divide and Conquer
  • DSA
  • subarray
  • subarray-sum
Practice Tags :
  • Arrays
  • Divide and Conquer

Similar Reads

  • Longest unique subarray of an Array with maximum sum in another Array
    Given two arrays X[] and Y[] of size N, the task is to find the longest subarray in X[] containing only unique values such that a subarray with similar indices in Y[] should have a maximum sum. The value of array elements is in the range [0, 1000]. Examples: Input: N = 5, X[] = {0, 1, 2, 0, 2}, Y[]
    10 min read
  • Maximum of XOR of first and second maximum of all subarrays
    Given an array arr[] of distinct elements, the task is to find the maximum of XOR value of the first and second maximum elements of every possible subarray.Note: Length of the Array is greater than 1. Examples: Input: arr[] = {5, 4, 3} Output: 7 Explanation: All Possible subarrays with length greate
    11 min read
  • Maximum OR value of a pair in an Array | Set 2
    Given an array arr[] of N positive elements, the task is to find the maximum bitwise OR value of a pair from the given array.Examples: Input: arr[] = {3, 6, 8, 16} Output: 24 Explanation: The pair giving maximum OR value is (8, 16) 8|16 = 24Input: arr[] = {8, 7, 3, 12} Output: 15 Explanation: There
    5 min read
  • C++ Program to Maximize elements using another array
    Given two arrays with size n, maximize the first array by using the elements from the second array such that the new array formed contains n greatest but unique elements of both the arrays giving the second array priority (All elements of second array appear before first array). The order of appeara
    4 min read
  • Maximum length of subarray such that sum of the subarray is even
    Given an array of N elements. The task is to find the length of the longest subarray such that sum of the subarray is even.Examples: Input : N = 6, arr[] = {1, 2, 3, 2, 1, 4}Output : 5Explanation: In the example the subarray in range [2, 6] has sum 12 which is even, so the length is 5.Input : N = 4,
    11 min read
  • Maximum OR value of a pair in an Array without using OR operator
    Given an array arr[] containing N positive integers, the task is to find the maximum bitwise OR value of a pair in the given array without using the Bitwise OR operator.Examples: Input: arr[] = {3, 6, 8, 16} Output: 24 Explanation: The pair giving maximum OR value is (8, 16) => 8|16 = 24Input: ar
    6 min read
  • Maximum length sub-array which satisfies the given conditions
    Given an array arr[] of N integers, the task is to find the maximum length of any sub-array of arr[] which satisfies one of the given conditions: The subarray is strictly increasing.The subarray is strictly decreasing.The subarray is first strictly increasing then strictly decreasing. Examples: Inpu
    9 min read
  • Sum of Max of Subarrays
    Given an array arr[], the task is to find the sum of the maximum elements of every possible non-empty sub-arrays of the given array arr[]. Examples: Input: arr[] = [1, 3, 2]Output: 15Explanation: All possible non-empty subarrays of [1, 3, 2] are {1}, {3}, {2}, {1, 3}, {3, 2} and {1, 3, 2}. The maxim
    12 min read
  • Minimize the maximum element of N subarrays of size K
    Given an array arr[] and two integers N and K, the task is to choose non-overlapping N subarrays of size K such that the maximum element of all subarrays is minimum.Note: If it is not possible to choose N such subarrays then return -1. Examples: Input: arr[] = {1, 10, 3, 10, 2}, N = 3, K = 1 Output:
    8 min read
  • Length of longest subarray for each index in Array where element at that index is largest
    Given an array arr[] of size N, the task is to calculate, for i(0<=i<N), the maximum length of a subarray containing arr[i], where arr[i] is the maximum element. Example: Input : arr[ ] = {62, 97, 49, 59, 54, 92, 21}, N=7Output: 1 7 1 3 1 5 1Explanation: The maximum length of subarray in which
    15 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences