Maximum circular subarray sum

Given n numbers (both +ve and -ve), arranged in a circle, fnd the maximum sum of consecutive number.

Examples:

Input: a[] = {8, -8, 9, -9, 10, -11, 12}
Output: 22 (12 + 8 - 8 + 9 - 9 + 10)

Input: a[] = {10, -3, -4, 7, 6, 5, -4, -1} 
Output:  23 (7 + 6 + 5 - 4 -1 + 10) 

Input: a[] = {-1, 40, -14, 7, 6, 5, -4, -1}
Output: 52 (7 + 6 + 5 - 4 - 1 - 1 + 40)

Method 1 There can be two cases for the maximum sum:

  • Case 1: The elements that contribute to the maximum sum are arranged such that no wrapping is there. Examples: {-10, 2, -1, 5}, {-2, 4, -1, 4, -1}. In this case, Kadane’s algorithm will produce the result.
  • Case 2: The elements which contribute to the maximum sum are arranged such that wrapping is there. Examples: {10, -12, 11}, {12, -5, 4, -8, 11}. In this case, we change wrapping to non-wrapping. Let us see how. Wrapping of contributing elements implies non-wrapping of non-contributing elements, so find out the sum of non-contributing elements and subtract this sum from the total sum. To find out the sum of non contributing, invert the sign of each element and then run Kadane’s algorithm.
    Our array is like a ring and we have to eliminate the maximum continuous negative that implies maximum continuous positive in the inverted arrays. Finally, we compare the sum obtained by both cases and return the maximum of the two sums.

Thanks to ashishdey0 for suggesting this solution.
Following are C/C++, Java and Python implementations of the above method.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for maximum contiguous circular sum problem
#include <bits/stdc++.h>
using namespace std;
  
// Standard Kadane's algorithm to
// find maximum subarray sum
int kadane(int a[], int n);
  
// The function returns maximum
// circular contiguous sum in a[]
int maxCircularSum(int a[], int n)
{
    // Case 1: get the maximum sum using standard kadane'
    // s algorithm
    int max_kadane = kadane(a, n);
  
    // Case 2: Now find the maximum sum that includes
    // corner elements.
    int max_wrap = 0, i;
    for (i = 0; i < n; i++) {
        max_wrap += a[i]; // Calculate array-sum
        a[i] = -a[i]; // invert the array (change sign)
    }
  
    // max sum with corner elements will be:
    // array-sum - (-max subarray sum of inverted array)
    max_wrap = max_wrap + kadane(a, n);
  
    // The maximum circular sum will be maximum of two sums
    return (max_wrap > max_kadane) ? max_wrap : max_kadane;
}
  
// Standard Kadane's algorithm to find maximum subarray sum
// See https:// www.geeksforgeeks.org/archives/576 for details
int kadane(int a[], int n)
{
    int max_so_far = 0, max_ending_here = 0;
    int i;
    for (i = 0; i < n; i++) {
        max_ending_here = max_ending_here + a[i];
        if (max_ending_here < 0)
            max_ending_here = 0;
        if (max_so_far < max_ending_here)
            max_so_far = max_ending_here;
    }
    return max_so_far;
}
  
/* Driver program to test maxCircularSum() */
int main()
{
    int a[] = { 11, 10, -20, 5, -3, -5, 8, -13, 10 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << "Maximum circular sum is " << maxCircularSum(a, n) << endl;
    return 0;
}
  
// This is code is contributed by rathbhupendra

chevron_right


C

filter_none

edit
close

play_arrow

link
brightness_4
code

// C program for maximum contiguous circular sum problem
#include <stdio.h>
  
// Standard Kadane's algorithm to find maximum subarray
// sum
int kadane(int a[], int n);
  
// The function returns maximum circular contiguous sum
// in a[]
int maxCircularSum(int a[], int n)
{
    // Case 1: get the maximum sum using standard kadane'
    // s algorithm
    int max_kadane = kadane(a, n);
  
    // Case 2: Now find the maximum sum that includes
    // corner elements.
    int max_wrap = 0, i;
    for (i = 0; i < n; i++) {
        max_wrap += a[i]; // Calculate array-sum
        a[i] = -a[i]; // invert the array (change sign)
    }
  
    // max sum with corner elements will be:
    // array-sum - (-max subarray sum of inverted array)
    max_wrap = max_wrap + kadane(a, n);
  
    // The maximum circular sum will be maximum of two sums
    return (max_wrap > max_kadane) ? max_wrap : max_kadane;
}
  
// Standard Kadane's algorithm to find maximum subarray sum
// See https:// www.geeksforgeeks.org/archives/576 for details
int kadane(int a[], int n)
{
    int max_so_far = 0, max_ending_here = 0;
    int i;
    for (i = 0; i < n; i++) {
        max_ending_here = max_ending_here + a[i];
        if (max_ending_here < 0)
            max_ending_here = 0;
        if (max_so_far < max_ending_here)
            max_so_far = max_ending_here;
    }
    return max_so_far;
}
  
/* Driver program to test maxCircularSum() */
int main()
{
    int a[] = { 11, 10, -20, 5, -3, -5, 8, -13, 10 };
    int n = sizeof(a) / sizeof(a[0]);
    printf("Maximum circular sum is %dn",
           maxCircularSum(a, n));
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for maximum contiguous circular sum problem
import java.io.*;
import java.util.*;
  
class MaxCircularSum {
    // The function returns maximum circular contiguous sum
    // in a[]
    static int maxCircularSum(int a[])
    {
        int n = a.length;
  
        // Case 1: get the maximum sum using standard kadane'
        // s algorithm
        int max_kadane = kadane(a);
  
        // Case 2: Now find the maximum sum that includes
        // corner elements.
        int max_wrap = 0;
        for (int i = 0; i < n; i++) {
            max_wrap += a[i]; // Calculate array-sum
            a[i] = -a[i]; // invert the array (change sign)
        }
  
        // max sum with corner elements will be:
        // array-sum - (-max subarray sum of inverted array)
        max_wrap = max_wrap + kadane(a);
  
        // The maximum circular sum will be maximum of two sums
        return (max_wrap > max_kadane) ? max_wrap : max_kadane;
    }
  
    // Standard Kadane's algorithm to find maximum subarray sum
    // See https:// www.geeksforgeeks.org/archives/576 for details
    static int kadane(int a[])
    {
        int n = a.length;
        int max_so_far = 0, max_ending_here = 0;
        for (int i = 0; i < n; i++) {
            max_ending_here = max_ending_here + a[i];
            if (max_ending_here < 0)
                max_ending_here = 0;
            if (max_so_far < max_ending_here)
                max_so_far = max_ending_here;
        }
        return max_so_far;
    }
  
    public static void main(String[] args)
    {
        int a[] = { 11, 10, -20, 5, -3, -5, 8, -13, 10 };
        System.out.println("Maximum circular sum is " + maxCircularSum(a));
    }
} /* This code is contributed by Devesh Agrawal*/

chevron_right


Python

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python program for maximum contiguous circular sum problem
  
# Standard Kadane's algorithm to find maximum subarray sum
def kadane(a):
    n = len(a)
    max_so_far = 0
    max_ending_here = 0
    for i in range(0, n):
        max_ending_here = max_ending_here + a[i]
        if (max_ending_here < 0):
            max_ending_here = 0
        if (max_so_far < max_ending_here):
            max_so_far = max_ending_here
    return max_so_far
  
# The function returns maximum circular contiguous sum in
# a[]
def maxCircularSum(a):
  
    n = len(a)
  
    # Case 1: get the maximum sum using standard kadane's
    # algorithm
    max_kadane = kadane(a)
  
    # Case 2: Now find the maximum sum that includes corner
    # elements.
    max_wrap = 0
    for i in range(0, n):
        max_wrap += a[i]
        a[i] = -a[i]
  
    # Max sum with corner elements will be:
    # array-sum - (-max subarray sum of inverted array)
    max_wrap = max_wrap + kadane(a)
  
    # The maximum circular sum will be maximum of two sums
    if max_wrap > max_kadane:
        return max_wrap
    else:
        return max_kadane
  
# Driver function to test above function
a = [11, 10, -20, 5, -3, -5, 8, -13, 10]
print "Maximum circular sum is", maxCircularSum(a)
  
# This code is contributed by Devesh Agrawal

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for maximum contiguous
// circular sum problem
using System;
  
class MaxCircularSum {
  
    // The function returns maximum circular
    // contiguous sum in a[]
    static int maxCircularSum(int[] a)
    {
        int n = a.Length;
  
        // Case 1: get the maximum sum using standard kadane'
        // s algorithm
        int max_kadane = kadane(a);
  
        // Case 2: Now find the maximum sum that includes
        // corner elements.
        int max_wrap = 0;
        for (int i = 0; i < n; i++) {
            max_wrap += a[i]; // Calculate array-sum
            a[i] = -a[i]; // invert the array (change sign)
        }
  
        // max sum with corner elements will be:
        // array-sum - (-max subarray sum of inverted array)
        max_wrap = max_wrap + kadane(a);
  
        // The maximum circular sum will be maximum of two sums
        return (max_wrap > max_kadane) ? max_wrap : max_kadane;
    }
  
    // Standard Kadane's algorithm to find maximum subarray sum
    // See https:// www.geeksforgeeks.org/archives/576 for details
    static int kadane(int[] a)
    {
        int n = a.Length;
        int max_so_far = 0, max_ending_here = 0;
        for (int i = 0; i < n; i++) {
            max_ending_here = max_ending_here + a[i];
            if (max_ending_here < 0)
                max_ending_here = 0;
            if (max_so_far < max_ending_here)
                max_so_far = max_ending_here;
        }
        return max_so_far;
    }
  
    // Driver code
    public static void Main()
    {
        int[] a = { 11, 10, -20, 5, -3, -5, 8, -13, 10 };
  
        Console.Write("Maximum circular sum is " + maxCircularSum(a));
    }
}
  
/* This code is contributed by vt_m*/

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
  
// PHP program for maximum 
// contiguous circular sum problem 
  
// The function returns maximum 
// circular contiguous sum $a[] 
function maxCircularSum($a, $n
    // Case 1: get the maximum sum 
    // using standard kadane' s algorithm 
    $max_kadane = kadane($a, $n); 
      
    // Case 2: Now find the maximum  
    // sum that includes corner elements. 
    $max_wrap = 0;
    for ($i = 0; $i < $n; $i++) 
    
            $max_wrap += $a[$i]; // Calculate array-sum 
            $a[$i] = -$a[$i]; // invert the array (change sign) 
    
      
    // max sum with corner elements will be: 
    // array-sum - (-max subarray sum of inverted array) 
    $max_wrap = $max_wrap + kadane($a, $n); 
      
    // The maximum circular sum will be maximum of two sums 
    return ($max_wrap > $max_kadane)? $max_wrap: $max_kadane
  
// Standard Kadane's algorithm to 
// find maximum subarray sum 
function kadane($a, $n
    $max_so_far = 0;
    $max_ending_here = 0; 
    for ($i = 0; $i < $n; $i++) 
    
        $max_ending_here = $max_ending_here +$a[$i]; 
        if ($max_ending_here < 0) 
            $max_ending_here = 0; 
        if ($max_so_far < $max_ending_here
            $max_so_far = $max_ending_here
    
    return $max_so_far
  
    /* Driver code */
    $a = array(11, 10, -20, 5, -3, -5, 8, -13, 10); 
    $n = count($a);
    echo "Maximum circular sum is ". maxCircularSum($a, $n); 
  
// This code is contributed by rathbhupendra
?>

chevron_right



Output:



Maximum circular sum is 31

Complexity Analysis:

  • Time Complexity: O(n), where n is the number of elements in input array.
    As only linear traversal of the array is needed.
  • Auxiliary Space: O(1).
    As no extra space is required.

Note that the above algorithm doesn’t work if all numbers are negative e.g., {-1, -2, -3}. It returns 0 in this case. This case can be handled by adding a pre-check to see if all the numbers are negative before running the above algorithm.

Method 2
Approach: In this method, modify Kadane’s algorithm to find a minimum contiguous subarray sum and the maximum contiguous subarray sum, then check for maximum value among the max_value and the value left after subtracting min_value from the total sum.

Algorithm

  1. We will calculate the total sum of the given array.
  2. We will declare variable curr_max, max_so_far, curr_min, min_so_far as the first value of the array.
  3. Now we will use Kadane’s Algorithm to find maximum subarray sum and minimum subarray sum.
  4. Check for all the values in the array:-
    1. If min_so_far is equaled to sum, i.e. all values are negative, then we return max_so_far.
    2. Else, we will calculate the maximum value of max_so_far and (sum – min_so_far) and return it.

C++ implementation of the above method is given below.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for maximum contiguous circular sum problem
#include <bits/stdc++.h>
using namespace std;
  
// The function returns maximum
// circular contiguous sum in a[]
int maxCircularSum(int a[], int n)
{
    // Corner Case
    if (n == 1)
        return a[0];
  
    // Initialize sum variable which store total sum of the array.
    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum += a[i];
    }
  
    // Initialize every variable with first value of array.
    int curr_max = a[0], max_so_far = a[0], curr_min = a[0], min_so_far = a[0];
  
    // Concept of Kadane's Algorithm
    for (int i = 1; i < n; i++) {
        // Kadane's Algorithm to find Maximum subarray sum.
        curr_max = max(curr_max + a[i], a[i]);
        max_so_far = max(max_so_far, curr_max);
  
        // Kadane's Algorithm to find Minimum subarray sum.
        curr_min = min(curr_min + a[i], a[i]);
        min_so_far = min(min_so_far, curr_min);
    }
  
    if (min_so_far == sum)
        return max_so_far;
  
    // returning the maximum value
    return max(max_so_far, sum - min_so_far);
}
  
/* Driver program to test maxCircularSum() */
int main()
{
    int a[] = { 11, 10, -20, 5, -3, -5, 8, -13, 10 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << "Maximum circular sum is " << maxCircularSum(a, n) << endl;
    return 0;
}

chevron_right



Output:

Maximum circular sum is 31

Complexity Analysis:

  • Time Complexity: O(n), where n is the number of elements in input array.
    As only linear traversal of the array is needed.
  • Auxiliary Space: O(1).
    As no extra space is required.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up