Largest Sum Contiguous Subarray

Write an efficient C program to find the sum of contiguous subarray within a one-dimensional array of numbers which has the largest sum.

Kadane’s Algorithm:

Initialize:
    max_so_far = 0
    max_ending_here = 0

Loop for each element of the array
  (a) max_ending_here = max_ending_here + a[i]
  (b) if(max_ending_here < 0)
            max_ending_here = 0
  (c) if(max_so_far < max_ending_here)
            max_so_far = max_ending_here
return max_so_far

Explanation:
Simple idea of the Kadane's algorithm is to look for all positive contiguous segments of the array (max_ending_here is used for this). And keep track of maximum sum contiguous segment among all positive segments (max_so_far is used for this). Each time we get a positive sum compare it with max_so_far and update max_so_far if it is greater than max_so_far

    Lets take the example:
    {-2, -3, 4, -1, -2, 1, 5, -3}

    max_so_far = max_ending_here = 0

    for i=0,  a[0] =  -2
    max_ending_here = max_ending_here + (-2)
    Set max_ending_here = 0 because max_ending_here < 0

    for i=1,  a[1] =  -3
    max_ending_here = max_ending_here + (-3)
    Set max_ending_here = 0 because max_ending_here < 0

    for i=2,  a[2] =  4
    max_ending_here = max_ending_here + (4)
    max_ending_here = 4
    max_so_far is updated to 4 because max_ending_here greater 
    than max_so_far which was 0 till now

    for i=3,  a[3] =  -1
    max_ending_here = max_ending_here + (-1)
    max_ending_here = 3

    for i=4,  a[4] =  -2
    max_ending_here = max_ending_here + (-2)
    max_ending_here = 1

    for i=5,  a[5] =  1
    max_ending_here = max_ending_here + (1)
    max_ending_here = 2

    for i=6,  a[6] =  5
    max_ending_here = max_ending_here + (5)
    max_ending_here = 7
    max_so_far is updated to 7 because max_ending_here is 
    greater than max_so_far

    for i=7,  a[7] =  -3
    max_ending_here = max_ending_here + (-3)
    max_ending_here = 4

Program:

    #include<stdio.h>
    int maxSubArraySum(int a[], int size)
    {
       int max_so_far = 0, max_ending_here = 0;
       int i;
       for(i = 0; i < size; 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 maxSubArraySum*/
    int main()
    {
       int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};
       int n = sizeof(a)/sizeof(a[0]);
       int max_sum = maxSubArraySum(a, n);
       printf("Maximum contiguous sum is %d\n", max_sum);
       getchar();
       return 0;
    }

Notes:
Algorithm doesn't work for all negative numbers. It simply returns 0 if all numbers are negative. For handling this we can add an extra phase before actual implementation. The phase will look if all numbers are negative, if they are it will return maximum of them (or smallest in terms of absolute value). There may be other ways to handle it though.

Above program can be optimized further, if we compare max_so_far with max_ending_here only if max_ending_here is greater than 0.

    int maxSubArraySum(int a[], int size)
    {
       int max_so_far = 0, max_ending_here = 0;
       int i;
       for(i = 0; i < size; i++)
       {
         max_ending_here = max_ending_here + a[i];
         if(max_ending_here < 0)
             max_ending_here = 0;

         /* Do not compare for all elements. Compare only   
            when  max_ending_here > 0 */
         else if (max_so_far < max_ending_here)
             max_so_far = max_ending_here;
       }
       return max_so_far;
    }

Time Complexity: O(n)
Algorithmic Paradigm: Dynamic Programming

Following is another simple implementation suggested by Mohit Kumar. The implementation handles the case when all numbers in array are negative.

#include<stdio.h>

int max(int x, int y)
{ return (y > x)? y : x; }

int maxSubArraySum(int a[], int size)
{
   int max_so_far = a[0], i;
   int curr_max = a[0];

   for (i = 1; i < size; i++)
   {
        curr_max = max(a[i], curr_max+a[i]);
        max_so_far = max(max_so_far, curr_max);
   }
   return max_so_far;
}

/* Driver program to test maxSubArraySum */
int main()
{
   int a[] =  {-2, -3, 4, -1, -2, 1, 5, -3};
   int n = sizeof(a)/sizeof(a[0]);
   int max_sum = maxSubArraySum(a, n);
   printf("Maximum contiguous sum is %d\n", max_sum);
   return 0;
}

Now try below question
Given an array of integers (possibly some of the elements negative), write a C program to find out the *maximum product* possible by adding 'n' consecutive integers in the array, n <= ARRAY_SIZE. Also give where in the array this sequence of n integers starts.


References:
http://en.wikipedia.org/wiki/Kadane%27s_Algorithm

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.





  • sujeet singh

    I have tried in this way – // not all number are -ve

    int get_sum_array(int * arr,int start_index,int end_index)
    {
    int sum = 0;
    for(;start_index <= end_index;start_index++)
    sum = sum+(*(arr+start_index));
    return sum;
    }

    int max_sum_subarray(int *arr,int array_size)
    {
    int start_index =0;
    int end_index =0;
    int max_sum = *(arr+start_index);
    for(int i = start_index;i < array_size-1;i++)
    {
    if(max_sum max_sum)
    max_sum = current_sum;
    }
    }
    return max_sum > 0 ? max_sum : 0;
    }

  • Venu Gopal

    http://ideone.com/NruDUY
    very short function, better than first version and works for all negative elements without any special arrangement..
    Edit: I just wrote this code after reading the first method only, but later when I read the method-2, I found out that my method is same as 2nd method.. sorry for that πŸ˜›

  • Rohit Kumar

    #include

    #include

    int cnt=0,cnt2;

    int maxSubArraySum(int a[], int size)

    {

    int max_so_far = 0, max_ending_here = 0;

    int i;

    for(i = 0; i < size; i++)

    {

    max_ending_here = max_ending_here + a[i];

    if(max_ending_here < 0)

    { max_ending_here = 0; cnt=i+1;}

    if(max_so_far < max_ending_here)

    { max_so_far = max_ending_here; cnt2=i;}

    }

    return max_so_far;

    }

    /*Driver program to test maxSubArraySum*/

    int main()

    {

    int i;

    int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};

    int n = sizeof(a)/sizeof(a[0]);

    int max_sum = maxSubArraySum(a, n);

    printf("Maximum contiguous sum is %dn", max_sum);

    for(i=cnt;i<=cnt2;i++)

    {

    printf(" %d ",a[i]);

    }

    getchar();

    return 0;

    }

  • Karthic

    For implementation of above program in java, please check the below page:

    http://myvedham.blogspot.in/2014/02/blog-post.html

  • NewCoder

    Java code to print the subarray along with the maxSum:

    public static void findMaxSumContiguousSubArray(int a[]) {

    int maxSum = a[0];
    int currentMaxSum = a[0];
    int maxStart = 0;
    int maxEnd = 0;
    int start = 0;
    int end = 0;
    for (int i = 1; i = a[i] + currentMaxSum) {
    start = i;
    end = i;
    currentMaxSum = a[i];
    } else {
    end = i;
    currentMaxSum = a[i] + currentMaxSum;
    }

    if (currentMaxSum > maxSum) {
    maxSum = currentMaxSum;
    maxStart = start;
    maxEnd = end;
    }
    }

    for (int i = maxStart; i <= maxEnd; i++) {
    System.out.print(a[i] + " ");
    }
    System.out.println();
    System.out.println(maxSum);
    }

  • nitin

    Hi,

    Could you please let me know, how to print the indexes also for the max sub array ie start and end..

  • prashant

    /*

    #include

    using namespace std;

    int max(int a,int b)

    {

    return a>b?a:b;

    }

    int max(int a,int b,int c)

    {

    return (max((max(a,b)),c));

    }

    int fun(int arr[],int low,int high,int sum)

    {

    if(low==high)

    return arr[low]>0?sum+arr[low]:sum;

    if((arr[low]0)

    return (fun(arr,low+1,high,sum+arr[low]));

    else

    return max(sum,fun(arr,low+1,high,sum+arr[low]),fun(arr,low+1,high,0));

    }

    int main()

    {

    int arr[]={-2, -3, 4, -1, -2, 1, 5, -3};

    int n=sizeof(arr)/sizeof(arr[0]);

    cout<<fun(arr,0,n-1,0)<<" is the max contiguos sum.n";

    return 0;

    }

    */

  • Prateek Kumar

    I suppose the line curr_max = max(a[i], curr_max+a[i]) should be replaced by curr_max = max(curr_max, curr_max+a[i]).

  • J

    The above code line ‘max_ending_here = max_ending_here + arr[i] ‘ should be ‘max_ending_here = max_so_far + arr[i];’

    • J

      Revoke my previous comment…thats a different algo altogether

  • sriram

    Solution two for the case of {1,2,-1,1,3};
    Shouldnt the answer be 4, instead it shows up as 6. Correct me if am wrong here

    • pankaj joshi

      the ans is 6 because from 1 till 3 all selected will give you max sum of 6 (you can select continiously no matter negative number comes in between)

  • Wing

    The second problem seems not working as expected

  • Om Prakash Gupta

    Input:[-1]
    Output:0
    Expected:-1

    algorithm fails for the above case

    • Dhruv

      The second algo is working just fine. The original kadane’s algo does not work in the case of an array with all the numbers negative. (it is already mentioned).

  • 7jan

    Hi regarding the solution provided by Mohit kumar, Is it correct for the case :

    {-40,1,40,-50,1,50,-20,1,20,0,0}

    Please let me know if I am missing some point.

    • akash

      yeah the max subarray is 1+50+(-20)+1+20 = 52

  • Amit Baghel

    Interesting πŸ˜€

  • pinkfloyda

    Actually, this is one algorithm that is very simple but hard to understand, can check up my block for more discussions http://comtechstash.wordpress.com/2013/11/19/intuitive-thinking-for-counter-intuitive-algorithms/

  • Amit Kumar

    I broke my head a lot to understand how it has to be implemented using Dynamic algo. But it has a very easy solution:

    public class MaxSum {

    public static int sum=0;

    public static void main(String[] args) {

    int super_max =0;

    int array[]={-2,-3,4,-1,-2,1,5,-3,-9,-10,-4,-5,-8,-6};

    for (int i=0; i= min){

    return max;

    }

    else{

    return min;

    }

    }

    }

  • mayank verma

    The algorithm paradigm should be “greedy” why it is considered as “Dynamic programming”

    • Swagat

      Because each step in the algorithm is making use of optimal solutions for the sub problems calculated before that step.

      • thinklazy

        But there is no memorisation, just sub problem alone should not qualify for DP.

        • thinklazy

          My bad.. you are right. It qualifies for DP.

  • Guest

    #include
    main(){
    int i, n, a[100], max = 0, sum = 0;
    scanf(“%d”,&n);
    for(i = 0; i <n ; i++)
    scanf("%d",&a[i]);
    max = a[0];
    for(i = 1; i < n; i++)
    {
    sum+=a[i];
    if(max < sum)
    max = sum;
    if(sum < 0)
    sum = 0;
    }
    printf("%d", max);
    return 0;
    }
    This will work for all cases.

  • timus

    thank you..

  • shashi_kr

    public static void main(String[] args){

    int []A={2, 8, -3, 6, -13, 4, 7, 2, -18, 19, -17, 8, -16, 10};
    int b=maxSum(A);
    System.out.print(b);
    }

    static int maxSum(int [] A){
    int maxS=A[0], sum=0;
    int n=A.length;
    for(int i=0; imaxS){
    maxS=sum;
    }
    }
    }
    return maxS;
    }
    }

  • Born Actor
     
    #include <iostream>
    #include<string>
    #include<sstream>
    #include<iomanip>
    # include <stdio.h>
    # include <math.h>
    #include <vector>
    #include <stdlib.h>
    using namespace std;
    int n;
    pair < int , pair < int , int > > function(int i, int j);
    pair < int , pair < int , int > > function2(int i, int m, int j);
    pair < int , pair < int , int > > max(pair < int , pair < int , int >  > a,pair < int , pair < int , int >  > b ,pair < int , pair < int , int >  > c);
    int a[50];
    int main()
    {
    	int i,j;
    	cout<<"etner the size of the arraay";
    	cin>>n;
    	for(i=0;i<n;i++)
    		cin>>a[i];
    	pair < int , pair < int , int >  > temp;
    	temp=function(0,n-1);
    	cout<<temp.first<<"  "<< temp.second.first<<"  " <<temp.second.second<<endl;
    }
     pair < int , pair < int ,int > >function(int l, int r)
    {
    	//base case
    	if(l==r)
    		return make_pair (a[l] , make_pair (l,l ) );
    	if(r==l+1)
    	{
    		if(a[r]>0 && a[l]>0)
    			return make_pair (a[l]+a[r] , make_pair (l,r ) );
    		if(a[r]==0 && a[l]>0)
    			return make_pair (a[l] , make_pair (l,l ) );
    		if(a[r]<0 && a[l]>0)
    			return make_pair (a[l] , make_pair (l,l ) );
    		if(a[r]>0 && a[l]<0)
    			return make_pair (a[r] , make_pair (r,r ) );
    		if(a[r]==0 && a[l]<0)
    			return make_pair (a[r] , make_pair (r,r ) );
    		if(a[r]<0 && a[l]<0 && a[r] > a[l])
    			return make_pair (a[r] , make_pair (r,r ) );
    		if(a[r]<0 && a[l]<0 && a[r]<a[l])
    			return make_pair (a[l] , make_pair (l,l ) );
    		if(a[r]>0 && a[l]==0)
    			return make_pair (a[r] , make_pair (r,r ) );
    		if(a[r]==0 && a[l]==0)
    			return make_pair (a[l] , make_pair (l,l ) );
    		if(a[r]<0 && a[l]==0)
    			return make_pair (a[l] , make_pair (l,l ) );
    	}
    
    	int m =( l+r)/2;
    	pair < int , pair < int , int >  > temp;
    		
    	pair < int , pair < int , int >  > temp1;
    
    	pair < int , pair < int , int >  > temp2;
    	pair < int , pair < int , int >  > temp3;
    	temp1= function(l,m);
    	temp2=function(m,r);
    	temp3=function2(l,m,r);
    	temp= max(temp1,temp2,temp3);
    	return temp;
    
    
    }
    pair < int , pair < int ,int > > function2(int l ,int m, int r )
    {
    	//base case;
    	pair < int , pair < int , int >  > temp;
    	int max_l=-9999;
    	int sum_l=0;
    	int max_r=-9999;
    	int sum_r=0;
    	int right=m;
    	int left=m;
    	int temp2=0;
    	int i,j;
    	for(i=m;i<=r;i++)
    	{
    		sum_r=sum_r+a[i];
    		if(sum_r>max_r)
    		{
    			max_r=sum_r;
    			right = i;	
    		}
    	}
    	for(i=m-1;i>=l;i--)
    	{
    		sum_l=sum_l+a[i];
    		if(sum_l>max_l)
    		{
    			max_l=sum_l;
    			left = i;	
    		}
    	}
    	return make_pair( (max_r+max_l) , make_pair(left,right));
    }
    pair < int , pair < int , int >  > max (pair < int , pair < int , int >  > a , pair < int , pair < int , int >  > b,   pair < int , pair < int , int >  > c)
    {
    	pair < int , pair < int , int >  > max1;
    	max1 = a;
    	if(b.first>max1.first)
    		max1=b;
    	if(c.first>max1.first)
    		max1=c;
    	return max1;
    }
     
  • kanhaiya

    here is a simple program working for all negative and positive no. give me feedback if anything wrong

    /* Paste your code here (You may delete these lines if not writing co */
    [#include
    #include
    using namespace std;
    int main()
    {int cases;
    cin>>cases;//enter the no. of cases you want to check
    while(cases–)
    {int n;
    cin>>n;//enter the no. of element in the array
    int arr[n];
    for(int i=0;i>arr[i];//enter the elements
    int dp[n];
    dp[0]=arr[0];
    int max=dp[0];
    for(int i=1;i<n;i++)
    {dp[i-1]dp[i]?(max):max=dp[i];
    }
    cout<<max<<endl;
    }
    }]

  • ultimate_coder

    Also working for all negative numbers.

     
    void kadane(int a[],int size)
    {
        int max_here=0,max_end=0,flag=0,cpy=a[0];
        for(int i=0;i<size;i++)
        {
            if(a[i]>0) flag=1;
            max_here+=a[i];
            if(max_here<0)
            {
                if(cpy<a[i])
                cpy=a[i];
                max_here=0;
    
            }
            if(max_here>max_end)
            max_end=max_here;
        }
        if(!flag) cout<<"MAX IS : "<<cpy;
        else
        cout<<"MAX IS : "<<max_end;
    }
     
  • Pratyay

    #include
    #include
    int maxSubArraySum(int *);
    int maxSubArraySum(int *arr)
    {
    int *sum = (int *)calloc(sizeof(int),8);
    int i,large = arr[0];
    sum[0] = arr[0];
    for (i=1;i= 0)
    {
    if (sum[i-1] < 0)
    sum[i] = arr[i];
    else
    sum[i] = sum[i-1] + arr[i];
    }
    if (arr[i] = 0))
    {
    sum[i] = sum[i-1] + arr[i];
    }
    else if(arr[i] < 0 && (arr[i]+sum[i-1] large)
    large = sum[i];
    }
    return large;
    }

    int main()
    {
    int arr[] = {-2,-3,4,-1,-2,1,5,-3};
    printf(“Maximum sum – %d”,maxSubArraySum(arr));
    getchar();
    return;
    }

  • Achawla

    Given an array of integers (possibly some of the elements negative), write a C program to find out the *maximum product* possible by adding ‘n’ consecutive integers in the array, n <= ARRAY_SIZE.

    #include <iostream>
    #include <conio.h>
    using namespace std;
    int main(){
    int prev=-999,sum=1,cur_pos=1,prev_pos,Max=-99;
    int a[]={9, -7, 3, 0, 2, 4, 0, -5, 0, -8};
    for(int i=0; i<8; i++){
    sum*=a[i];
    if(sum<0 && prev >0){
    prev_pos=prev;
    }
    else if (sum<0){
    if(i!=0)
    cur_pos*=a[i];
    }
    else if(sum>0){
    Max=Max>sum?Max:sum;
    prev_pos=sum;
    }
    else if(sum == 0){
    Max= Max>prev_pos? Max:prev_pos;
    Max= Max>cur_pos? Max:cur_pos;
    cur_pos=1;
    sum=1;
    }
    prev=sum;
    }
    cout<<"\nMaximum product: "<<Max;
    getch();
    return 0;
    }

  • Nishank

    If an array consists of all negative number then what should be the answer 0 or the smallest negative in array.

  • startre
     
    //another possible solution may be this(working for -ve numbers)
    
    void max_subarray()
    {
        int arr[]={-1,2,-3,4,-5,6,-7,9,-8};
        int size=9;
         //kedan's solution modified..
         
         int max_here=arr[0],max_far=0;
         for(int i=0;i<size;i++)
         {
                 
                 if(max_here < 0 && arr[i] >=max_here)
                             max_here=arr[i];
                 else if( max_here > 0)
                             max_here+=arr[i];
                 if(max_here > max_far)
                             max_far=max_here;
                  
         }
         if(max_far==0)
                   cout<<"max:"<<max_here;               
         else
                   cout<<"max:"<<max_far;
    }
     
  • http://instagram.com/lokeshguddu/ Invictus

    If we use memoization than we do not need to consider extra case of all numbers being egative.

    #include <algorithm>
    #include <iostream>
    #include <limits>

    using namespace std;

    int maxSubsequenceSum(int arr[], int n)
    {
    if(n==1)
    return arr[0];
    int sum[n];
    sum[0] = arr[0];
    int maxSum = numeric_limits<int>::min();
    for (int i = 1; i < n; ++i)
    {
    sum[i] = max(sum[i-1]+arr[i], arr[i]);
    if(sum[i] > maxSum)
    maxSum = sum[i];
    }
    return maxSum;
    }

    int main()
    {
    int arr[] = {-2,-3,-4,-1,-2,-1,-5,-3};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << maxSubsequenceSum(arr, n) << endl;
    return 0;
    }

    • alien

      if memoization is used, space complexity is increased from o(1) to o(n). I think Mohit’s algorithm is the optimal solution.

  • sid
     
    /* 
    #include<stdio.h>
    #include<stdlib.h>
    int main()
    {
        int *a, n, maxsum, sum=0, i, b, c, d;
        printf("enter no of elements:");
        scanf("%d",&n);
        a=(int *)malloc(sizeof(int)*n);
        printf("enter elements\n");
        for(i=0;i<n;i++)
            scanf("%d",(a+i));
        maxsum=a[0];
        d=0;
        for(i=0;i<n;i++)
        {
            sum += a[i];
            if(sum > maxsum)
            {
                b=d;
                maxsum = sum;
                c=i;
            }
            if(sum < 0)
            {
                sum=0;
                d=i+1;
            }
        }
        printf("maximum sum is %d\n",maxsum);
        if(maxsum == 0)
            printf("all elements are 0\n");
        else if(maxsum < 0)
        {
            sum=0;
            for(i=1;i<n;i++)
                if(a[sum] < a[i])
                    sum=i;
            printf("max sum is from %d to %d\n", sum, sum);
        }
        else
        printf("maximum sum is from %d to %d\n",b+1, c+1);
        return 0;
    }
    
     */
     
  • atulb_dce

    For taking care of cases where number are not positive… do this..
    If a represents current max. sum, and b represents max. sum so far
    then at each element arr[i] do following :

    while (i

  • cooldude

    /* public int kadaneAlgorithm(int[] input)
    {
    int maxSum=input[0];
    int sum=0;
    for(int i=0;i<input.length;i++)
    {
    sum=sum+input[i];
    if(sum>maxSum)
    maxSum=sum;
    if(sum<0)
    sum=0;

    }
    return maxSum;
    } */

  • mohitk

    A much better and shorter approach:
    Also the same can easily be modified to keep track of the sub-array indices.

     
    public static kadane(int[] array) {
    	int max = array[0], currMax = array[0];
    	
    	for (int i = 1; i < array.length; i++) {
    		currMax = Math.max(array[i], currMax + array[i]);
    		max = Math.max(max, currMax);
    	}
    	
    	return max;
    }
     
    • mohitk

      The above one can be used for any type of input.
      +ve, -ve and a mix.

      Also to handle the edge cases the following can be the start of the method :

      public int kadane (int[] array) {
      if (array == null || array.length == 0) return Integer.MIN_VALUE;
      if (array.length == 1) return array[0];
      ..
      }

      • aygul

        Very nice and short one. thanks…

      • Pavi

        @geeksforgeeks: solution by mohitk looks elegant, simple, covers all cases (as far as I can see) and seems to be providing optimal sol. for all cases. My request to you is to mention the above solution in your main article (as an alternate sol. or otherwise),if possible, so that other will also believe on the correctness of this sol. If you think otherwise about the correctness of this sol. then please let me your comments.

        @Mohitk: Thanks buddy for sharing this sol.

        • mohitk

          @Pavi,
          thanks.
          Yups, submitted a request for the same to the moderators.
          Lets see whether they also feel that my solution is correct.

      • Code123

        Nope, ds s actually wrong. For the present case, your code will give the answer 9 which is very clear. For reference, just see: http://ideone.com/mredxe

        Hope it helps! :)

        • pavi

          @code123
          For the link u pasted and the instance for which its solved, I see 9 as the only max solution for input {-2,-3,4,-1,-2,5,3}.
          How is it wrong? and what max do u expect it to give ?

          I think you got it wrong. The input considered here at geeksforgeeks is this: {-2, -3, 4, -1, -2, 1, 5, -3}
          and its diff from the one at ideone.

          Hope it helps now :)

          • code1234

            oops my bad! thnxs dude! it surely helps! πŸ˜€

             
            /* Paste your code here (You may delete these lines if not writing code) */
             
      • code1234

        Nope, ds s actually wrong. For the present case, your code will give the answer 9 which is very clear. For reference, just see: http://ideone.com/mredxe

        Hope it helps!:)

         
        /* Paste your code here (You may delete these lines if not writing code) */
         
  • finalmusic5

    A little bit modification on Kadane’s algo will work

     
    class Solution {     //DP,but with less memory
    public:
        int maxSubArray(int A[], int n) {
            // Start typing your C/C++ solution below
            // DO NOT write int main() function
            int maxendinghere=0,maxsofar=-9999;
            for(int i=0;i<n;i++){
                if(maxendinghere<=0)maxendinghere=A[i];
                else maxendinghere+=A[i];
                if(maxendinghere>maxsofar)maxsofar=maxendinghere;
            }
            return maxsofar;
        }
    };
     
  • Prince
     
    #include<stdio.h>
    int main () {
    	
    	int a[] = {-2, -13, 4, -1, -2, 1, 5, -3}; // All working including start and end index
    	// int a[] = {-1, 0, -12}; // All working
    	// int a[] = {-2, -13, 4, -3, -2, 1, 5, -3}; - // For this particular case, all working except wrong start index
    	int size = sizeof(a) / sizeof(a[0]);
    	int sum = a[0], maxsum = a[0];
    	int start = 0, end = 0;
    
    	for(int i=1; i<size ;i++) {
    		if(sum + a[i] <= 0){
    			// -ve +ve, sum = a[i]
    			// +ve -ve, sum = a[i]
    			// -ve -ve, sum = a[i]
    			sum = a[i];
    			start = i;
    		} else	{
    			// -ve +ve, sum = a[i]
    			// +ve -ve, add
    			// +ve +ve, add
    			if(sum < 0) {
    				sum = a[i];
    				start = i;
    			} else {
    				sum = sum + a[i];
    			}
    		}
    
    		if(maxsum < sum) {
    			maxsum = sum;
    			end = i;
    		}
    
    		// Resetting start and end index for -ve numbers
    		if(start > end) {
    			start = end;
    		}
    	}
    
    	printf("Max sum = %d, start index = %d, end index = %d\n", maxsum, start, end);
    	return 0;
    } 
  • Ankit

    // A perfect code, it also take into count if all numbers are negative
    #include
    #include
    #include
    using namespace std;
    int main()
    {
    int n;
    printf(“Enter size of array : “);
    scanf(“%d”,&n);
    int a[n],i;
    printf(“Enter elements of array : “);
    for(i=0;i<n;i++)
    scanf("%d",a+i);

    int start,end,sum,maxsum,ind;
    sum=start=ind=0;
    maxsum=INT_MIN;
    for(i=0;isum)
    {
    sum=a[i];
    ind=i;
    }
    if(sum>maxsum)
    {
    start=ind;
    maxsum=sum;
    end=i;
    }
    }
    printf(“sum=%d, start=%d, end=%d\n”,maxsum,start+1,end+1);
    return 0;
    }

    • ashish

      int max_add(int ary[])
      {
      int i,cur_max=0,max_value=0,c=0,min=INT_MIN;

      for(i=0;i<5;i++)
      {
      cur_max+=ary[i];
      if(ary[i]<0)
      {
      c++;
      if(min<ary[i])
      min=ary[i];
      }

      if(cur_max<0)
      cur_max=0;
      else
      if(max_value<cur_max)
      max_value=cur_max;

      if(c==5)
      max_value=min;
      }
      return max_value;
      }

    • Guest

      Handle all negatives:
      1. Scan for all elements to find out if all are negative (O(n))

      2. if yes, then find the largest element in the array (O(n)).
      3. else,

      int sum=0; int max=0; int start=-1, end=-1;
      for(int i=0; i<n; i++)
      {
      sum=sum+a[i];
      if(summax) {
      max=sum;
      if(a[i]==max) {
      start=i; end=i;

      } else {
      end=i;

      }

      }

      }

  • http://shashank7s.blogspot.com Shashank

    @All shouldn’t be when all no are -ive , maximum of them will be largest subarray thats nothing but only of length or i am missing something ??

     
    /* Paste your code here (You may delete these lines if not writing code) */
     
  • bin01

    Solution for max product. The idea is to precompute the number of negative numbers after a given index. If there is 0 is between, we restart the count.

     
    	int maxProduct(int[] a) {
    		int global_max = 0;
    		int local_max = 0;
    		int[] x = numNegatives(a);
    		for (int i = 0; i < a.length; ++i) {
    			if (a[i] > 0 || (a[i] < 0 && x[i] >= 1) || (local_max < 0 && a[i] < 0)) {
    				local_max = (local_max == 0) ? a[i] : local_max * a[i];
    			} else {
    				local_max = 0;
    			}
    
    			if (global_max < local_max) {
    				global_max = local_max;
    			}
    		}
    		return global_max;
    	}
    
    	int[] numNegatives(int[] a) {
    		int[] x = new int[a.length];
    		int count = 0;
    		for (int n = (a.length - 1); n >= 0; --n) {
    			x[n] = count;
    			if (a[n] == 0) {
    				count = 0;
    			}
    			if (a[n] < 0) {
    				count++;
    			}
    		}
    		return x;
    	}
     
    • kvmahesh

      I think it does not work if one of the elements in array is 0

      • kvmahesh

        sorry yaar,it works

        • Nikin

          This doesn’t work for input 2, -1, 3, 4,-5,-6,0,1,3,-2,-1.

          It gives 120 as output. But the solution is 360

           
          /* Paste your code here (You may delete these lines if not writing code) */
           
          • himanshu

            infact it is giving the correct answer because we have to find “maxProduct subArray” not the maximum product of the array..

    • KP

      I don’t think the code works for following example,
      {-2, 1, 1, -5, -15, 5}
      The solution should be -5*-15 = 75, but the output is 10

       
      /* Paste your code here (You may delete these lines if not writing code) */
       
  • manish

    class MaxSubarray {
    public static void main(String[] args) {

    int[] intArr = {-2, -3, 4, -1, -2, 1, 5, -3};
    //int[] intArr = {3,1,2,-4,5,9,-11,6,7};
    //int[] intArr = {-1,-2,-3,-4,-5,-99};
    //int[] intArr = {-1,0,0,0,0,0};
    int maxSubArraySum = printMaxSumArr(intArr,intArr.length);
    System.out.println(“maxSubArraySum->”+maxSubArraySum);
    }

    public static int printMaxSumArr(int[] a, int n) {
    int maxSum=0;
    int minNeg=0;
    boolean allNegative=true;
    int[] saveSum = new int[n];
    saveSum[0]=a[0];
    if(a[0]>0){
    allNegative =false;
    }
    else {
    minNeg=a[0];
    }
    for(int i = 1; i =0){
    allNegative=false;
    }
    else {
    minNeg=(minNeg>a[i]?minNeg:a[i]);
    }
    saveSum[i]=max(saveSum[i-1]+a[i],a[i]);
    if(saveSum[i]>maxSum) {
    maxSum=saveSum[i];
    }

    }
    if(allNegative){
    return minNeg;
    }
    return maxSum;
    }

    private static int max(int i, int j) {
    return (i>j?i:j);
    }
    }

    • manish
       
      class MaxSubarray {
      	 public static void main(String[] args) {
      		 
      	        int[] intArr = {-2, -3, 4, -1, -2, 1, 5, -3};
      	        //int[] intArr = {3,1,2,-4,5,9,-11,6,7};
      	        //int[] intArr = {-1,-2,-3,-4,-5,-99};
      	        //int[] intArr = {-1,0,0,0,0,0};
      	        int maxSubArraySum = printMaxSumArr(intArr,intArr.length);
      	        System.out.println("maxSubArraySum->"+maxSubArraySum);
      	    }
      	 
      	    public static int printMaxSumArr(int[] a, int n) {
      	        int maxSum=0;
      	        int minNeg=0;
      	        boolean allNegative=true;
      	        int[] saveSum = new int[n];
      	        saveSum[0]=a[0];
      	        if(a[0]>0){
      	        	allNegative =false;
      	        }
      	        else {
      	        	minNeg=a[0];
      	        }
      	        for(int i = 1; i < a.length; i++) {
      	        	if(a[i]>=0){
      	        		allNegative=false;
      	        	}
      	        	else {
      	        		minNeg=(minNeg>a[i]?minNeg:a[i]);
      	        	}
      	        	saveSum[i]=max(saveSum[i-1]+a[i],a[i]);
      	        	if(saveSum[i]>maxSum) {
      	        		maxSum=saveSum[i];
      	        	}
      	        	
      	        }
      	        if(allNegative){
      	        	return minNeg;
      	        }
      	        return maxSum;
      	    }
      
      		private static int max(int i, int j) {
      			return (i>j?i:j);
      		}
      	}
       
      • manish

        This is the correct one..

  • Ankit Gupta

    No cases required.

     
    #define forn(i, n) for(int i = 0; i < (int)(n); i++)
    #define maX(a,b) ((a > b) ? a : b)
    
    // minend is max till here (-ve or +ve)
    // max total max
    int maxsumcont(vector<int> a)
    {
        int max = -INF, minend = 0;
        forn(i, a.size()) {
            max = maX(maX(a[i], minend+a[i]), max);
            minend = maX(minend+a[i], a[i]);
        }
    
        return max;
    }
     
  • supercooluku

    What if I want to print the elements from which the Largest Sum is formed…

    For ex: int a[]={2,4,-4,-1,2,8,-30,3,8};
    should print
    2,4,-4,-1,2,8
    AND
    3,8

  • kapil
     
        void findMaxSubArray(int *ar,int n,int &maxSum,int & startIndex, int & startIndex)
        {
            int maxSum = INT_MIN; // minimum integer value use #include<climits>
            int sum = ar[0];
            for(int i = 1;i<n;i++)
            {
                sum+=ar[i];
                if( ar[i] > sum)
                {   startIndex = i;    sum = ar[i];      }
                if(sum>maxSum)
                {   maxSum = sum;      endIndex = i;    }
            }
        }
     
    • kapil

      its working for all the cases… as I have checked… if any mistake then plse let me know..

      • krazykoder

        hey nice, this looks the most optimized version

        I think 1 correction should be there to update endindex=i when updating startindex=i;
        consider last index a[n-1]>sum . then startindex=n-1; while endindex <n-1

        or to remove unwanted extra condition that may be needed when printing sol.

        /* Paste your code here (You may delete these lines if not writing code) */

        void findMaxSubArray(int *ar,int n,int &maxSum,int & startIndex, int & endIndex)
        {
        int maxSum = INT_MIN; // minimum integer value use #include<climits>
        int sum = ar[0];
        for(int i = 1;i<n;i++)
        {
        sum+=ar[i];
        if( ar[i] > sum)
        { startIndex = i;
        sum = ar[i];
        endIndex = i;
        }
        if(sum>maxSum)
        {
        maxSum = sum;
        endIndex = i; }
        }
        }

    • Ankit

      your code will give incorrect answer.
      test case : 4 5 -15 1 2

       
      /* Paste your code here (You may delete these lines if not writing code) */
       
  • bikash sharma

    nice and amazing

     
    /* Paste your code here (You may delete these lines if not writing code) */
     
  • sparco

    @geeksforgeeks

    If all elements are negative the function will return zero ,
    interchanging the if and elseif should work.
    Correct me if i am wrong

    if (max_so_far < max_ending_here)
    max_so_far = max_ending_here;
    else if(max_ending_here < 0)
    max_ending_here = 0;

    • shri

      It’s not if/else-if, rather if/if.
      if(condition)
      ..
      if(condition)
      ..

      and I don’t think interchanging them will affect the working of program.

  • pranav
     
    /* Paste your code here (You may delete these lines if not writing code) */
    //Fully working C code
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {   int n=0;
        printf("enter the number of elements in the array\n");
        scanf("%d",&n);
        int a[100],start=0,end=0;
        printf("\n enter the elements in the array \n");
        int i=0;
        for(i=0;i<n;i++)
         scanf("%d",&a[i]);
    
        int max=0 , current=0;
        //For handling all negative numbers
      /*  for(j=0;j<n;j++){
              if(a[j] <0)
                sum = max(a[j]);
    
             }*/
        for(i=0;i<n;i++)
         {
    
            current += a[i];
    
            if(current < 0)
             { current =0;
               start =i+1;
             }
            if( max < current)
             { max = current;
               end = i;
             }
    
         }
    
        printf("MAX SUM between indexes a[%d]=%d and a[%d]=%d = %d",start,a[start],end,a[end],max);
        return 0;;
    }
    
    
    
     
  • http://www.groupme.in Nikin Kumar Jain

    Code Can Work for Negative Numbers by placing a simple flag.

    Check out the Code below.

     
    // MaxSubArray1.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    
    int maxSumArray(int a[], int len)
    {
    	int max_sum = -32768;
    	int max_here = 0;
    	int flag = 0;
    	for(int i=0;i<len;i++)
    	{
    		max_here += a[i];
    		if(max_here < 0)
    		{
    			max_here = 0;
    			if(!flag)
    			{
    				if(max_sum < a[i])
    					max_sum = a[i];
    			}
    		}
    		else if(max_sum < max_here) {
    			max_sum = max_here;
    			flag = 1;
    		}
    	}
    	return max_sum;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int a[] = {-2, -3, -4, -1, -2, -1, -5, -3};
    	cout<<maxSumArray(a,8);
    	return 0;
    }
    
    
     
  • VJVALOR
     
    void max_sum_sub_array(int *a, int n, int *start, int *end, int *max_sum)
    {
        int m_sum = 0x80000000; // min32
        int sum = 0;
        int i_start = 0;
        int i_end = 0;
        int s = 0;
        int i = 0;
        
        for(i = 0; i < n; i++)
        {
            sum += a[i];
            
            if(sum > m_sum)
            {
                m_sum = sum;
                i_start = s;
                i_end = i;
            }
            
            if(sum < 0)
            {
                sum = 0;
                s = i + 1;
            }
        }
        
        *start = i_start;
        *end = i_end;
        *max_sum = m_sum;
        
    }
     
  • Asquare

    I guess there is better way to handle all negative numbers.
    The following algo will take in account negative as well as positive numbers.

    Initialize:
    max_so_far = a[0]
    max_ending_here = 0

    Loop for each element of the array
    (a) max_ending_here = max_ending_here + a[i]
    (b) if(max_ending_here < a[i])
    max_ending_here = a[i]
    (c) if(max_so_far < max_ending_here)
    max_so_far = max_ending_here
    return max_so_far

    And so subsequently the code would change automatically.. What say??

    • prakhar

      yupp,…perfect

    • novice.c

      Agree.

  • fred

    Is it possible to get the starting and end index of the subarray?

     
    /* Paste your code here (You may delete these lines if not writing code) */
     
    • aggarwald2002

      Look at the code in one of my comments below. It returns a MaxSubArrayVO which also includes the sub-array-range along with the sum.

    • manas
       
      public class MaxSubArray {
      
      	public static void main(String[] args) {
      
      		int[] intArr = toIntArray(args);
      		printMaxSumArr(intArr);
      	}
      
      	public static void printMaxSumArr(int[] in) {
      
      		int subStart = -1;
      		int subEnd = -1;
      
      		int subStartCurr = -1;
      
      		int sumHere = 0;
      		int sumMax = 0;
      
      		boolean isChangeSubStart = false;
      
      		for(int i = 0; i < in.length; i++) {
      
      			if(sumHere == 0) {
      				subStartCurr = -1;
      			}
      
      			sumHere = sumHere + in[i];
      			if(sumHere < 0) {
      				sumHere = 0;
      			}
      
      			if(subStartCurr == -1 && sumHere > 0) {
      				subStartCurr = i;
      			}
      
      			if(sumHere > sumMax) {
      				sumMax = sumHere;
      				subEnd = i;
      				isChangeSubStart = true;
      			}
      
      			if(isChangeSubStart) {
      				subStart = subStartCurr;
      			}
      
      		}
      
      		System.out.println("MaxSum = " + sumMax);
      		String subArr = "";
      		for(int i = subStart; i <= subEnd; i++) {
      			subArr = subArr + " " + in[i];
      		}
      		System.out.println("SubArray =" + subArr);
      	}
      
      	public static int[] toIntArray(String[] strArr) {
      
      		int[] intArr = new int[strArr.length];
      		for(int i = 0; i < strArr.length; i++) {
      			intArr[i] = Integer.parseInt(strArr[i]);
      		}
      
      		return intArr;
      	}
      
      }
       
    • manas

      Edited code with some comments:

       
      public class MaxSubArray {
      
      	public static void main(String[] args) {
      
      		/* Modify string array to int array */
      		int[] intArr = toIntArray(args);
      
      		/* Print max sum and corresponding sub array */
      		printMaxSumArr(intArr);
      	}
      
      	public static void printMaxSumArr(int[] in) {
      
      		int subStart = -1;
      		int subEnd = -1;
      
      		int subStartCurr = -1;
      
      		int sumHere = 0;
      		int sumMax = 0;
      
      		for(int i = 0; i < in.length; i++) {
      
      			/* If corresponding to last element was 0, the sub array with a positive sum has not started yet */
      			if(sumHere == 0) {
      				subStartCurr = -1;
      			}
      
      			sumHere = sumHere + in[i];
      			if(sumHere < 0) {
      				sumHere = 0;
      			}
      
      			/* If sum is positive and the sub array has not yet started, start it */
      			if(subStartCurr == -1 && sumHere > 0) {
      				subStartCurr = i;
      			}
      
      			if(sumHere > sumMax) {
      				sumMax = sumHere;
      				/* New max sum found. Time to change start and end index of sub array */
      				subEnd = i;
      				subStart = subStartCurr;
      			}
      
      		}
      
      		System.out.println("MaxSum = " + sumMax);
      		String subArr = "";
      		for(int i = subStart; i <= subEnd; i++) {
      			subArr = subArr + " " + in[i];
      		}
      		System.out.println("SubArray =" + subArr);
      	}
      
      	public static int[] toIntArray(String[] strArr) {
      
      		int[] intArr = new int[strArr.length];
      		for(int i = 0; i < strArr.length; i++) {
      			intArr[i] = Integer.parseInt(strArr[i]);
      		}
      
      		return intArr;
      	}
      
      }
       
  • var

    It should run for both positive and negative inputs.

     
    
    int maxSubArraySum(int []a, int size)
            {
               int max_so_far = 0, max_ending_here = 0;
    
               if (size > 0)
               {
                   max_so_far = a[0];
                   max_ending_here = a[0];
               }
    
               int i;
               for(i = 1; i < size; i++)
               {
                   if (a[i - 1] < 0 && max_ending_here< 0)
                   {
                       max_ending_here = a[i];
                   }
                   else
                   {
                       max_ending_here += a[i];
                   }
    
                 /* Do not compare for all elements. Compare only
                    when  max_ending_here > 0 */
                 //else
                   if (max_so_far < max_ending_here)
                     max_so_far = max_ending_here;
               }
               return max_so_far;
            }
     
    • var

      Sorry,I forgot to remove comments as comments mentioned in post is irrelevant.

  • PsychoCoder

    This code is working for negative numbers also. The array containing all negative numbers.

     
    int getLargestSumContiguousSubarray (int *arr, int size ) {
      int i, max_so_far = *arr , max_end_here = *arr;
      for ( i = 1 ; i < size ; i ++ ) {
        max_end_here += arr[i] ;
        if ( max_end_here > max_so_far )
          max_so_far = max_end_here ;
        if ( max_end_here < 0 ) 
          max_end_here = 0 ;
      }
      return max_so_far ;
    } 
    • Prashant Gupta

      How to handle this case.. i want the starting and end position both….
      -1 -2 -3 0 0 0 -4 -5 0 0 0 -9

       
      /* Paste your code here (You may delete these lines if not writing code) */
       
  • donbosio

    a little modification to find start and end index of the subarray:

    int max_sum(int *a,int n)
    {
    int max_so_far=0;
    int max_ending_here=0;
    int s,e;
    s=e=-1;
    for(i=0;i<=n-1;i++)
    {
    max_ending_here=max_ending_here+a[i];
    if(max_ending_here<0)
    {
    max_ending_here=0;
    s=i+1;
    }
    else if(max_so_far<max_ending_here)
    {
    max_so_far=max_ending_here;
    e=i;
    }
    }
    if(max_so_far==0)
    {
    s=-1;
    e=-1;
    }
    }

    • Shadi

      This is not working for {1, 2}, start will be -1.
      This solution will be ok:
      int max_sum(int[] a, int n) {
      int max_so_far = 0;
      int max_ending_here = 0;
      int s, e, largest;
      s = e = largest = 0;
      for (int i = 0; i a[largest]) largest = i;
      max_ending_here = max_ending_here + a[i];
      if (max_ending_here < 0) {
      max_ending_here = 0;
      s = i + 1;
      } else if (max_so_far < max_ending_here) {
      max_so_far = max_ending_here;
      e = i;
      }
      }
      if (a[largest] 0) ? max_so_far : a[largest];
      }

  • Anand
  • Hill

    The program is not working for {1,2,-1,3,4}

    its returning 9 which is the sum of entire array. the expected result is 7

    • GeeksforGeeks

      @Hill. 9 is the correct answer for your input array. The array itself is considered one of the subarrays of the array.

  • m2010ok

    Input:
    5 -2 8 3 -11 13 2 1 -1 0 3 8 -30 31 -4 3 -12
    Max Ending Here:
    5 3 11 14 3 16 18 19 18 18 21 29 -1(0) 31 27 30 18
    Max_SoFar
    ——————————–29——-30 26 29 17

    So is the answer 31 or 30 or 29?

    • Tracy

      It is 31.

  • Tracy

    This should work for all negatives case,without iterating the array more than once,so please verify it.

     
    int maxSubArraySum(int a[],int size)
    { 
      //note this algorithm does not work for all negative numbers
      int max_ending_here = 0,max_sum = 0;
      int i =0 ;
      int largest_num = 0x80000000; //the smallest integer if int's size is 4 bytes
    
      for(; i< size;i++)
      {
        if(a[i]>largest_num) largest_num = a[i];
    
        max_ending_here += a[i];
        //if is negative,recount the max_ending_here
        if(max_ending_here < 0) 
         max_ending_here =0;
       
        else if(max_sum < max_ending_here) 
            max_sum = max_ending_here;
      }//for
      return (largest_num > 0)?max_sum:largest_num;
    }
     
    • Tracy

      sorry,the first comment line should be removed.

  • hari babu
    def max_subarray(A):
        max_so_far = max_ending_here = 0
        for x in A:
            max_ending_here = max(0, max_ending_here + x)
            max_so_far = max(max_so_far, max_ending_here)
        return max_so_far
    
  • ravikant

    Can somebody explain to me how is this algo DYNMAMIC PROGRAMMING ???????????
    this is nothing except smart thinking
    also can somebody give a dynamic programming solution for the problem ???
    or even a recursive relation would do

    • kartik

      @ravikant:
      Refer to the below lines @http://en.wikipedia.org/wiki/Maximum_subarray_problem
      “Because of the way this algorithm uses optimal substructures (the maximum subarray ending at each position is calculated in a simple way from a related but smaller and overlapping subproblem, the maximum subarray ending at the previous position) this algorithm can be viewed as a simple example of dynamic programming”

    • aggarwald2002

      The below code is an example of top-down algorithm using recursion. It returns a value object that encapsulates (max-sum, lowerIndexOfSubArray, upperIndexOfSubArray).

       
      public class MaximalSubArray {
      
      	public static class MaxSubArrayVO {
      		public int sum;
      		public int lowerIndex;
      		public int upperIndex;
      
      		public MaxSubArrayVO(int sum, int lower, int upper) {
      			this.sum = sum;
      			this.lowerIndex = lower;
      			this.upperIndex = upper;
      		}
      
      		public int range() {
      			return upperIndex - lowerIndex;
      		}
      	}
      
      	/**
      	 * Finds maximal-sub-array (sub-array whose sum is maximum) within the given input array of 
      	 * +ve and -ve integers. It uses recursion and caches intermediate recursion results in a table (2-D array)
      	 * 
      	 * @param array input array of +ve and -ve integers
      	 * @param startIndex lower index of the range of numbers to consider in the array
      	 * @param endIndex upper index of the range of numbers to consider in the array
      	 * @param maxSubArrayTable 2-D array that stores intermediate recursion results.
      	 * 
      	 * @return maximal-sub-array-Value-Object that encapsulates (sum, lowerIndexOfSubArray, upperIndexOfSubArray).
      	 */
      	private static MaxSubArrayVO findMaximalSubArray(int[] array,
      			int startIndex, int endIndex, MaxSubArrayVO[][] maxSubArrayTable) {
      		if (endIndex < 0 || endIndex > array.length - 1 || startIndex < 0
      				|| startIndex > array.length - 1) {
      			return null;
      		}
      		// sub-array length = 1
      		if (endIndex == startIndex) {
      			if (array[endIndex] > 0) {
      				return new MaxSubArrayVO(array[startIndex], startIndex,
      						startIndex);
      			} else {
      				// return 0 for a -ve number
      				return new MaxSubArrayVO(0, startIndex, startIndex);
      			}
      		}
      
      		// find maximal subarray in array-subset[startIndex, endIndex -1]
      		if (maxSubArrayTable[startIndex][endIndex - 1] == null) {
      			maxSubArrayTable[startIndex][endIndex - 1] = findMaximalSubArray(
      					array, startIndex, endIndex - 1, maxSubArrayTable);
      		}
      		MaxSubArrayVO maxSubArrInSubsetOfArray = maxSubArrayTable[startIndex][endIndex - 1];
      
      		if (maxSubArrInSubsetOfArray != null
      				&& endIndex == (maxSubArrInSubsetOfArray.upperIndex + 1)) {
      			// current element is contiguous to maxsubarray found in
      			// array-subset[startIndex, endIndex -1]
      			if (maxSubArrInSubsetOfArray.sum > 0) {
      				int newSum = array[endIndex] + maxSubArrInSubsetOfArray.sum;
      
      				if (newSum > 0) {
      					return new MaxSubArrayVO(newSum,
      							maxSubArrInSubsetOfArray.lowerIndex, endIndex);
      				} else {// currentElement cannot be part of maxsubarray
      					return maxSubArrInSubsetOfArray;
      				}
      			} else { // sum of maxsubarray in array-subset(startIndex ->
      						// endIndex -1) is 0 or -ve
      				if (array[endIndex] > 0) {
      					return new MaxSubArrayVO(array[endIndex], endIndex,
      							endIndex);
      				} else {
      					// return 0 for a -ve number
      					return new MaxSubArrayVO(0, endIndex, endIndex);
      				}
      			}
      		} else {
      			// current element is NOT contiguous to maxsubarray in
      			// array-subset[startIndex, endIndex -1]
      			if (maxSubArrInSubsetOfArray.sum > 0) {
      				if (array[endIndex] > maxSubArrInSubsetOfArray.sum) {
      					// currentElement is larger than maxsubarray found so far
      					return new MaxSubArrayVO(array[endIndex], endIndex,
      							endIndex);
      				} else {
      					if (maxSubArrayTable[endIndex][array.length - 1] == null) {
      						maxSubArrayTable[endIndex][array.length - 1] = findMaximalSubArray(
      								array, endIndex, array.length - 1,
      								maxSubArrayTable);
      					}
      					return max(maxSubArrayTable[endIndex][array.length - 1],
      							maxSubArrInSubsetOfArray);
      
      				}
      
      			} else { // sum of array-subset[startIndex, endIndex -1] is 0 or
      						// -ve
      				if (array[endIndex] > 0) {
      					return new MaxSubArrayVO(array[endIndex], endIndex,
      							endIndex);
      				} else {
      					// return 0 for a -ve number
      					return new MaxSubArrayVO(0, endIndex, endIndex);
      				}
      			}
      		}
      
      	}
      
      	/**
      	 * Returns subarrayVO whose sum is maximum; if sum is equal, then longer
      	 * subarray gets preference.
      	 */
      	private static MaxSubArrayVO max(MaxSubArrayVO sub1, MaxSubArrayVO sub2) {
      		return sub1.sum > sub2.sum ? sub1 : ((sub1.sum == sub2.sum) && (sub1
      				.range() > sub2.range())) ? sub1 : sub2;
      	}
      
      	/**
      	 * @param args
      	 */
      	public static void main(String[] args) {
      		// input array
      		int[] array = new int[] { 6, 4, -11, 7, 6, -2, 0, -15, -1, -3, 25, 2,
      				-3, 4 };
      
      		// table that caches intermediate results; [i][j] denote the range of
      		// subarray
      		MaxSubArrayVO[][] maxSubArrayTable = new MaxSubArrayVO[array.length][array.length];
      
      		MaxSubArrayVO maxSubArrVO = findMaximalSubArray(array, 0,
      				array.length - 1, maxSubArrayTable);
      		System.out.println("Max sum = " + maxSubArrVO.sum);
      		System.out.println("lower index = " + maxSubArrVO.lowerIndex);
      		System.out.println("upper Index = " + maxSubArrVO.upperIndex);
      	}
      }
       
      • aggarwald2002

        omg, the above code was in java and the formatting has gone for a toss :-( I tried to edit it later but didn’t find this feature. Apologies to the folks…

  • Aravind_Sen

    why doesnt input a[] = {-2, -3, 4, -4, 50, 5, -3};
    work in kadane’s algorithm

    it gives me output as 2293724

    • edvox1138

      Check you array size parameter.
      I added your test array and got 55.

       
      int arrAravind_Sen[] = {-2, -3, 4, -4, 50, 5, -3};
      	max = testCaseHelper(arrAravind_Sen,(sizeof(arrAravind_Sen)/sizeof(int)), 55);
       
      • Aravind_Sen

        thanks..

  • http://anuragsharma-sun.blogspot.com/ crazyFrog

    What if all elements in the array are negative. Will it not return 0 in this case which is wrong?
    Correct me if I am missing something

    • edvox1138

      Possible solution for an array input with all negative numbers:
      // initialize max_so_far to the first element of the array
      max_so_far = a[0];

      { -1, -20, -4, -5 } returns -1
      { -10, -5, -3, -2 } returns -2

      • kartik

        Initializing max_so_far to the first element of the array might not work as we also have below condition in the code.

         
        if(max_ending_here < 0)
           max_ending_here = 0; 
        • edvox1138

          You are correct. So along with the initialization code. I modified the following code:

             
          // guarantee an array of at least one element
             if(a == 0) return 0;
             if(size < 1) return 0;
             max_so_far = a[0];
          
          ...
          
          //if(max_ending_here < 0)
          //   max_ending_here = 0;
          // condition to start a new subarray to sum
           if(max_ending_here < a[i]) 
               max_ending_here = a[i];
          
          result of test cases so far:
          /*
          testCase: arr=  0 max = 0 passed
          testCase: arr=  -99 max = -99 passed
          testCase: arr=  34 max = 34 passed
          testCase: arr=  0 1 2 3 4 5 max = 15 passed
          testCase: arr=  99 1 10 2 4 max = 116 passed
          testCase: arr=  34 0 1 12 10 max = 57 passed
          testCase: arr=  1 -9 4 5 6 -1 2 max = 16 passed
          testCase: arr=  1 -9 4 5 6 -10 2 max = 15 passed
          testCase: arr=  1 -9 4 5 6 -16 45 max = 45 passed
          testCase: arr=  1 -9 4 5 6 -10 45 max = 50 passed
          testCase: arr=  -1 -9 -2 -3 -4 -5 0 max = 0 passed
          testCase: arr=  -99 -1 -10 -2 -4 max = -1 passed
          testCase: arr=  -34 -5 -1 -12 -1 max = -1 passed
          */
           

          The test cases above do not cover all cases, but it looks promising.

          • Amol

            Following code works for all cases. I think checking for max_present<0, is needed here.

            #include <iostream>
            using namespace std;
            int main() {

            int arr[]={-2,-3,4,-1,-2,-7,-5,-3};
            int max_present,max_all,i;
            max_present=0;
            max_all=arr[0];
            for(i=0;i<8;i++)
            {
            max_present+=arr[i];
            if(max_all<max_present){
            max_all=max_present;
            }
            if(max_present<0){
            max_present=0;
            }
            }
            cout<<"Max sum is "<<max_all;
            return 0;

            }

  • Asit

    In this example {-2, -3, 4, -1, -2, 1, 5, -3}..shouldn’t 6 be the answer (1 and 5)…we’re getting 4 which i feel isn’t correct. Please correct me if I’m wrong.

    • GeeksforGeeks

      @Asit: The program doesn’t return 4, it returns 7 (4 + -1 + -2 + 1 + 5). In function maxSubArraySum(), we return max_so_far, not max_ending_here (whose final value is 4).

      • Asit

        Sorry, my mistake.I considered max_ending_here instead of max_so_far

  • ab

    uh… I think there’s a typo in the example? The critical 6th index reads:

    for i=6, a[6] = 1
    … etc …

    The element at a[6] is 5, not 1. The rest of the statement it correct, but that assignment error might be confusing to a non-programmer trying to understand the explanation of algorithm? I’ve been programming for a while, and I still did a triple take until I found the typo.

    Or, is this a test to see if the readers can debug pseudo-code? πŸ˜‰

    • GeeksforGeeks

      @ab: Thanks for pointing this out. We have corrected the typo.

    • Gautham

      :) @ab, for your question, answer is no. We do not want to test readers by introducing bugs. There are smarter ways of doing so. (Obvious one being the Q&A section). But I guess this made you understand the solution better πŸ˜‰

  • geeksforgeeks

    @Hary: Your solution works fine.

    One thing to add – When count of negative numbers is odd, we need to check product of left and right for both first and last negative elements. So we need to get max of these four products.

    Thanks for writing the solution. Keep writing to us!

    • abhimanu

      Here is the code as discussed by you and Hary.

       
      #include<stdio.h>
      int max(int a, int b)
      {
      	int max_num;
      	return (a>b ? a:b);
      
      }
      int maxSubArrayProd(int a[], int size)
      {
         int max_so_far = 1;
         int i;
         //stores number of negative entries
         int num_of_neg=0;
         //stores first negative entries if any
         int first_neg;
         //stores last negative entries if any
         int last_neg;
         int prod_so_far_right_of_last_neg=1;
         int prod_so_far_left_for_first_neg=1;
         int prod_so_far_left=1;
         int prod_so_far_right=1;
         int prod_so_far_middle=1;
         int prod_right_of_last_neg=1;
         int prod_left_of_last_neg=1;
         int prod_left_of_first_neg=1;
         int prod_right_of_first_neg=1;
      
         for(i = 0; i < size; i++)
         {
      	   if (a[i] < 0)
      	   {
      		   if (num_of_neg == 0) {
      			   first_neg = i;
      		   }
      		   num_of_neg++;
      		   last_neg = i;
      	   }
         }
         if ((num_of_neg%2 == 0) || (num_of_neg == 0)) {
      	   //multiply all
      	   for(i = 0; i < size; i++)
      	   {
      		max_so_far *= a[i];
      	   }
      	   return max_so_far;
         } else if (num_of_neg == 1) {
      	   //only one negative number
      	   //find prod of left and write numbers
      	   for(i = 0; i < first_neg; i++)
      	   {
      		prod_so_far_left *= a[i];
      	   }
      	   for(i = first_neg+1; i < size; i++)
      	   {
      		prod_so_far_right *= a[i];
      	   }
      	   return max(prod_so_far_left, prod_so_far_right);
         } else {
      	   //more than one odd negative numbers
      	   for(i = 0; i < first_neg; i++)
      	   {
      		prod_so_far_left_for_first_neg *= a[i];
      	   }
      	   for(i = first_neg+1; i < last_neg; i++)
      	   {
      		prod_so_far_middle *= a[i];
      	   }
      	   for(i = last_neg+1; i < size; i++)
      	   {
      		prod_so_far_right_of_last_neg *= a[i];
      	   }
      	   prod_left_of_first_neg = prod_so_far_left_for_first_neg;
      	   prod_right_of_first_neg = prod_so_far_middle * prod_so_far_right_of_last_neg * a[last_neg];
      	   prod_left_of_last_neg = prod_so_far_left_for_first_neg * a[first_neg] * prod_so_far_middle;
      	   prod_right_of_last_neg = prod_so_far_right_of_last_neg;
      
      	   return (max(max(prod_right_of_last_neg, prod_left_of_last_neg), 
      				   max(prod_right_of_first_neg, prod_left_of_first_neg)));
         }
      }
       
      /*Driver program to test maxSubArraySum*/
      int main()
      {
         int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};
         int max_prod = maxSubArrayProd(a, 8);
         printf("Maximum contiguous prod is %d\n", max_prod);
         return 0;
      }
       
      • anonymous

        what if 0 is one of the element

      • Nagaraju

        for input
        {-2, -3, 4, 0, -2, 1, 5, -3};

        result is wrong
        Maximum contiguous prod is 0

        tested code coping to
        http://ideone.com/o8g7Rl

         
        /* Paste your code here (You may delete these lines if not writing code) */
         
  • Hary

    Ok, as far as the all negative and all positive are concerned
    you dont have to worry because in case of all positive – just add the entire array to get the result – in case of all negative – just find out the smalles no in terms of magnitude.

    The problem becomes sensible only when you have a blend of negative and positive nos.

    As far as the “product variant” of this ques is listed above:
    I would say just find out the no of negative elements. If they are even, find the product of all the nos in the array , If the no of negative elements is odd then scan the array to find the last negative element. Find out the product of all the elements on one side of it – call it product left – and similarly for all the elements on the right of it – call them product right.

    Yield which ever is greater .

    Please correct me if i am missing something

  • geeksforgeeks

    Hi Raj, as mentioned in the notes, the algorithm doesn’t work for all negative numbers.

    For handling this we can add an extra phase before actual implementation. The phase will look if all numbers are negative, if they are it will return maximum of them (or smallest in terms of absolute value). There may be other ways to handle it though.

    Thanks for the comment, keep visiting us.

  • raj

    what if all the input values are negative.

    EX: {-2, -3, -4, -1, -2, -1, -5, -3}

    • edvox1138

      Possible solution for an array input with all negative numbers:
      max_so_far = a[0];
      // initialize to the first element of the array
      { -1, -20, -4, -5 } returns -1
      { -10, -5, -3, -2 } returns -2