0

I am having trouble implementing max sub array problem using divide and conquer.

Lets say I have an array [3,6,-1,2] and I want to find the max sum of this array in contiguous order. We can look at this and see that the sum is 10 from [0,3].

I tried implementing the pseudo code from my book but the answer is not correct.

// return (max-left, max-right, max sum left + right)
public static int[] maxcross(int[] array, int low, int mid, int high) {
    int leftSum = -10000000;
    int rightSum = -10000000;
    int sum = 0;
    int maxLeft=0;
    int maxRight=0;
    for(int i=mid;i<mid-low;i--){
        sum = sum + array[i];
        if(leftSum < sum){
            leftSum = sum;
            maxLeft = i;
        }
    }
    sum=0;
    for(int i=mid+1;i<high;i++){
        sum = sum + array[i];
        if(rightSum < sum){
            rightSum = sum;
            maxRight = i;
        }
    }
    int cross[] = {maxLeft,maxRight,leftSum+rightSum};
    return cross;
}

public static int[] maxsub(int array[], int low, int high){
    int[] maxSubLeft = new int[3];
    int[] maxSubRight = new int[3];
    int[] maxSub = new int[3];
    int[] maxSubCross = new int[3];
    int mid;
    if (high==low){
        maxSub[0] = low;
        maxSub[1] = high;
        maxSub[2] = array[low];
        return maxSub;
    }
    else{
        mid = (int) Math.floor((low+high)/2);
        maxSubLeft = maxsub(array,low,mid);
        maxSubRight = maxsub(array,mid+1,high);
        maxSubCross = maxcross(array,low,mid,high);

        if(maxSubLeft[2] >= maxSubRight[2] && maxSubLeft[2] >= maxSubCross[2])
            return maxSubLeft;
        else if(maxSubRight[2] >= maxSubLeft[2] && maxSubRight[2] >= maxSubCross[2])
            return maxSubRight;
        else
            return maxSubCross;
    }
}

I am getting this as the output

1

1

6

Can someone help me?

0

1 Answer 1

1

The recursive initial output is wrong in maxsub(...), return 0 when high=low and array[low] < 0;

public static int[] maxsub(int array[], int low, int high){
    int[] maxSubLeft = new int[3];
    int[] maxSubRight = new int[3];
    int[] maxSub = new int[3];
    int[] maxSubCross = new int[3];
    int mid;
    if (high==low){
        maxSub[0] = low;
        maxSub[1] = high;
        maxSub[2] = array[low];
        return maxSub; // if (array[low] < 0) return 0;
    }
    else{
        mid = (int) Math.floor((low+high)/2);
        maxSubLeft = maxsub(array,low,mid);
        maxSubRight = maxsub(array,mid+1,high);
        maxSubCross = maxcross(array,low,mid,high);

        if(maxSubLeft[2] >= maxSubRight[2] && maxSubLeft[2] >= maxSubCross[2])
            return maxSubLeft;
        else if(maxSubRight[2] >= maxSubLeft[2] && maxSubRight[2] >= maxSubCross[2])
            return maxSubRight;
        else
            return maxSubCross;
    }
}

By the way, your recursive algorithm is O(NlnN), a more effective and easy to implement algorithm is O(N), which applies the dynamic programming.

public static int maxSum(int array[], int low, int high) {
   int maxsum = 0, maxleftsum = 0;
   for (int i = low; i < high; i++) {
       maxsum = max(maxsum, array[i] + maxleftSum);
       maxleftSum = max(0, maxleftSum+array[i]);
   }
   return maxsum; // return the index if necessary. 
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.