最大子数组之和

一、最大和小于0时,和为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;
}

二、处理和为负

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;
}

三、输出起始位置

int sequence(std::vector<int> const & numbers)
{
    // Initialize variables here
    int max_so_far  = numbers[0], max_ending_here = numbers[0];

    // OPTIONAL: These variables can be added in to track the position of the subarray
    // size_t begin = 0;
    // size_t begin_temp = 0;
    // size_t end = 0;

    // Find sequence by looping through
    for(size_t i = 1; i < numbers.size(); i++)
    {
        // calculate max_ending_here
        if(max_ending_here < 0)
        {
            max_ending_here = numbers[i];

            // begin_temp = i;
        }
        else
        {
            max_ending_here += numbers[i];
        }

        // calculate max_so_far
        if(max_ending_here >= max_so_far )
        {
            max_so_far  = max_ending_here;

            // begin = begin_temp;
            // end = i;
        }
    }
    return max_so_far ;
}


bool invalid = false;

int maxSum(int a[],int n,int &start,int &end)
{
    if(a == NULL || n <= 0)
    {
        invalid = true;
        return 0;
    }
    invalid = false;
    int max_sum = 1<<31;
    int cur_sum = 0;
    int cur;
    for(int i = 0; i < n;i++)
    {
        if(cur_sum <= 0)
        {
            cur_sum = a[i];
            cur = i;
        }
        else
            cur_sum += a[i];
        if(cur_sum > max_sum)
        {
            max_sum = cur_sum;
            start = cur;
            end = i;
        }
    }
    return max_sum;
}

四、数组首尾相连

// 如果最大子数组跨界,那么剩余的中间那段和就一定是最小的
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
// kadane函数可根据题目要求按上面方法改进
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;
}

五、二维数组

// The main function that finds maximum sum rectangle in M[][]
void findMaxSum(int M[][COL])
{
    // Variables to store the final output
    int maxSum = INT_MIN, finalLeft, finalRight, finalTop, finalBottom;
 
    int left, right, i;
    int temp[ROW], sum, start, finish;
 
    // Set the left column
    for (left = 0; left < COL; ++left)
    {
        // Initialize all elements of temp as 0
        memset(temp, 0, sizeof(temp));
 
        // Set the right column for the left column set by outer loop
        for (right = left; right < COL; ++right)
        {
            // Calculate sum between current left and right for every row 'i'
            for (i = 0; i < ROW; ++i)
                temp[i] += M[i][right];
 
            // Find the maximum sum subarray in temp[]. The kadane() function
            // also sets values of start and finish.  So 'sum' is sum of
            // rectangle between (start, left) and (finish, right) which is the
            //  maximum sum with boundary columns strictly as left and right.
            sum = kadane(temp, &start, &finish, ROW);
 
            // Compare sum with maximum sum so far. If sum is more, then update
            // maxSum and other output values
            if (sum > maxSum)
            {
                maxSum = sum;
                finalLeft = left;
                finalRight = right;
                finalTop = start;
                finalBottom = finish;
            }
        }
    }
 
    // Print final values
    printf("(Top, Left) (%d, %d)\n", finalTop, finalLeft);
    printf("(Bottom, Right) (%d, %d)\n", finalBottom, finalRight);
    printf("Max sum is: %d\n", maxSum);
}


还有其他扩展。。。



你可能感兴趣的:(最大子数组之和)