Maximum circular subarray sum - GeeksforGeeks

29 Dec, 2021
Given n numbers (both +ve and -ve), arranged in a circle, find the maximum sum of consecutive numbers. 
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-contributions, 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 in both cases and return the maximum of the two sums.
Thanks to ashishdey0 for suggesting this solution. 
The following are implementations of the above method. 
C++
C
Java
Python
C#
PHP
Javascript
// C++ program for maximum contiguous circular sum problem#include <bits/stdc++.h>using namespace std; // Standard Kadane's algorithm to// find maximum subarray sumint 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);     // if maximum sum using standard kadane' is less than 0    if(max_kadane < 0)      return max_kadane;     // 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 detailsint 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_so_far < max_ending_here)            max_so_far = max_ending_here;          if (max_ending_here < 0)              max_ending_here = 0;    }    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
// C program for maximum contiguous circular sum problem#include <stdio.h> // Standard Kadane's algorithm to find maximum subarray// sumint 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 detailsint 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;}
// Java program for maximum contiguous circular sum problemimport java.io.*;import java.util.*; class Solution{    public static int kadane(int a[],int n){        int res = 0;        int x =  a[0];        for(int i = 0; i < n; i++){            res = Math.max(a[i],res+a[i]);            x= Math.max(x,res);        }        return x;    }  //lets write a function for calculating max sum in circular manner as discuss above    public static int reverseKadane(int a[],int n){        int total = 0;      //taking the total sum of the array elements        for(int i = 0; i< n; i++){            total +=a[i];                     }      // inverting the array        for(int i = 0; i<n ; i++){            a[i] = -a[i];        }      // finding min sum subarray        int k = kadane(a,n);//      max circular sum        int ress = total+k;       // to handle the case in which all elements are negative        if(total == -k ){            return total;        }        else{        return ress;        }             }     public static void main(String[] args)    {   int a[] = {1,4,6,4,-3,8,-1};        int n = 7;        if(n==1){             System.out.println("Maximum circular sum is " +a[0]);        }        else{                System.out.println("Maximum circular sum is " +Integer.max(kadane(a,n), reverseKadane(a,n)));        }    }} /* This code is contributed by Mohit Kumar*/
# Python program for maximum contiguous circular sum problem # Standard Kadane's algorithm to find maximum subarray sumdef kadane(a):    Max = a[0]    temp = Max    for i in range(1,len(a)):        temp += a[i]        if temp < a[i]:            temp = a[i]        Max = max(Max,temp)    return Max # 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.    # You can do so by finding the maximum negative contiguous    # sum    # convert a to -ve 'a' and run kadane's algo    neg_a = [-1*x for x in a]    max_neg_kadane = kadane(neg_a)     # Max sum with corner elements will be:    # array-sum - (-max subarray sum of inverted array)    max_wrap = -(sum(neg_a)-max_neg_kadane)     # The maximum circular sum will be maximum of two sums    res = max(max_wrap,max_kadane)    return res if res != 0  else max_kadane # Driver function to test above functiona = [11, 10, -20, 5, -3, -5, 8, -13, 10]print "Maximum circular sum is", maxCircularSum(a) # This code is contributed by Devesh Agrawal
// C# program for maximum contiguous// circular sum problemusing 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*/
<?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// See https://www.geeksforgeeks.org/archives/576 for detailsfunction 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?>
<script>    // javascript program for maximum contiguous circular sum problem     function kadane(a , n) {        var res = 0;        var x = a[0];        for (i = 0; i < n; i++) {            res = Math.max(a[i], res + a[i]);            x = Math.max(x, res);        }        return x;    }     // lets write a function for calculating max sum in circular manner as discuss    // above    function reverseKadane(a , n) {        var total = 0;        // taking the total sum of the array elements        for (i = 0; i < n; i++) {            total += a[i];        }        // inverting the array        for (i = 0; i < n; i++) {            a[i] = -a[i];        }        // finding min sum subarray        var k = kadane(a, n);        // max circular sum        var ress = total + k;        // to handle the case in which all elements are negative        if (total == -k) {            return total;        }        else {            return ress;        }     }          var a = [11, 10, -20, 5, -3, -5, 8, -13, 10];    var n = 9;    if (n == 1) {        document.write("Maximum circular sum is " + a[0]);    }      else {         document.write("Maximum circular sum is "            + Math.max(kadane(a, n), reverseKadane(a, n)));    } // This code is contributed by todaysgaurav</script>
Output: 
Maximum circular sum is 31
Complexity Analysis:  
Time Complexity: O(n), where n is the number of elements in the 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 the maximum value between the max_value and the value left after subtracting min_value from the total sum.Algorithm 
We will calculate the total sum of the given array.We will declare the variable curr_max, max_so_far, curr_min, min_so_far as the first value of the array.Now we will use Kadane’s Algorithm to find the maximum subarray sum and minimum subarray sum.Check for all the values in the array:- If min_so_far is equaled to sum, i.e. all values are negative, then we return max_so_far.Else, we will calculate the maximum value of max_so_far and (sum – min_so_far) and return it.
We will calculate the total sum of the given array.
We will declare the variable curr_max, max_so_far, curr_min, min_so_far as the first value of the array.
Now we will use Kadane’s Algorithm to find the maximum subarray sum and minimum subarray sum.
Check for all the values in the array:- If min_so_far is equaled to sum, i.e. all values are negative, then we return max_so_far.Else, we will calculate the maximum value of max_so_far and (sum – min_so_far) and return it.
If min_so_far is equaled to sum, i.e. all values are negative, then we return max_so_far.Else, we will calculate the maximum value of max_so_far and (sum – min_so_far) and return it.
If min_so_far is equaled to sum, i.e. all values are negative, then we return max_so_far.
Else, we will calculate the maximum value of max_so_far and (sum – min_so_far) and return it.
The implementation of the above method is given below.  
C++
Java
Python3
C#
Javascript
// 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;}
/*package whatever //do not write package name here */import java.io.*; class GFG {  public static 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 = Math.max(curr_max + a[i], a[i]);      max_so_far = Math.max(max_so_far, curr_max);       // Kadane's Algorithm to find Minimum subarray      // sum.      curr_min = Math.min(curr_min + a[i], a[i]);      min_so_far = Math.min(min_so_far, curr_min);    }    if (min_so_far == sum) {      return max_so_far;    }     // returning the maximum value    return Math.max(max_so_far, sum - min_so_far);  }   // Driver code  public static void main(String[] args)  {    int a[] = { 11, 10, -20, 5, -3, -5, 8, -13, 10 };    int n = 9;    System.out.println("Maximum circular sum is "                       + maxCircularSum(a, n));  }} // This code is contributed by aditya7409
# Python program for maximum contiguous circular sum problem # The function returns maximum# circular contiguous sum in a[]def maxCircularSum(a, n):         # Corner Case    if (n == 1):        return a[0]     # Initialize sum variable which    # store total sum of the array.    sum = 0    for i in range(n):        sum += a[i]     # Initialize every variable    # with first value of array.    curr_max = a[0]    max_so_far = a[0]    curr_min = a[0]    min_so_far = a[0]     # Concept of Kadane's Algorithm    for i in range(1, n):               # 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 codea = [11, 10, -20, 5, -3, -5, 8, -13, 10]n = len(a)print("Maximum circular sum is", maxCircularSum(a, n)) # This code is contributes by subhammahato348
// C# program for maximum contiguous circular sum problemusing System;class GFG{    public static 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 = Math.Max(curr_max + a[i], a[i]);            max_so_far = Math.Max(max_so_far, curr_max);             // Kadane's Algorithm to find Minimum subarray            // sum.            curr_min = Math.Min(curr_min + a[i], a[i]);            min_so_far = Math.Min(min_so_far, curr_min);        }        if (min_so_far == sum)        {            return max_so_far;        }         // returning the maximum value        return Math.Max(max_so_far, sum - min_so_far);    }     // Driver code    public static void Main()    {        int[] a = { 11, 10, -20, 5, -3, -5, 8, -13, 10 };        int n = 9;        Console.WriteLine("Maximum circular sum is "                          + maxCircularSum(a, n));    }} // This code is contributed by subhammahato348
<script>       // JavaScript program for the above approach         // The function returns maximum       // circular contiguous sum in a[]       function maxCircularSum(a, n) {           // Corner Case           if (n == 1)               return a[0];            // Initialize sum variable which store total sum of the array.           let sum = 0;           for (let i = 0; i < n; i++) {               sum += a[i];           }            // Initialize every variable with first value of array.           let curr_max = a[0], max_so_far = a[0], curr_min = a[0], min_so_far = a[0];            // Concept of Kadane's Algorithm           for (let i = 1; i < n; i++) {               // Kadane's Algorithm to find Maximum subarray sum.               curr_max = Math.max(curr_max + a[i], a[i]);               max_so_far = Math.max(max_so_far, curr_max);                // Kadane's Algorithm to find Minimum subarray sum.               curr_min = Math.min(curr_min + a[i], a[i]);               min_so_far = Math.min(min_so_far, curr_min);           }            if (min_so_far == sum)               return max_so_far;            // returning the maximum value           return Math.max(max_so_far, sum - min_so_far);       }        // Driver program to test maxCircularSum()        let a = [11, 10, -20, 5, -3, -5, 8, -13, 10];       let n = a.length;       document.write("Maximum circular sum is " + maxCircularSum(a, n));    // This code is contributed by Potta Lokesh    </script>
Output: 
Maximum circular sum is 31
Complexity Analysis:  
Time Complexity: O(n), where n is the number of elements in the input array. As only linear traversal of the array is needed.
Auxiliary Space: O(1). As no extra space is required.
rathbhupendra
its_sahil
andrew1234
aditya7409
subhammahato348
hectic
monuyadav94161
todaysgaurav
lokeshpotta20
akshaysingh98088
devakar305
circular-array
subarray
subarray-sum
Arrays
Arrays
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Top 50 Array Coding Problems for Interviews
Stack Data Structure (Introduction and Program)
Introduction to Arrays
Multidimensional Arrays in Java
Linear Search
Linked List vs Array
Python | Using 2D arrays/lists the right way
Search an element in a sorted and rotated array
Array of Strings in C++ (5 Different Ways to Create)