【编程题目】求子数组的最大和 ☆

3.求子数组的最大和(数组)
题目:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为 O(n)。
例如输入的数组为 1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为 3, 10, -4, 7, 2,
因此输出为该子数组的和 18。

 

算法里学过,动态规划。具体思路想不起来了,看了看书。要动态算1-i个元素中必须包括第i个元素的最大子段和C[i],A是原始序列

C[i + 1] = A[i + 1]             如果C[i]<0

               C[i] + A[i + 1]    如果C[i]>0

最后检查末尾是否有负数,若有去掉。

/*
3.求子数组的最大和(数组)
题目:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为 O(n)。
例如输入的数组为 1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为 3, 10, -4, 7, 2,
因此输出为该子数组的和 18。
*/

#include <stdio.h>
#include <stdlib.h>

int Max_Sum(int * a, int len)
{
    int * c = (int *)malloc(sizeof(int) * len); //存包括第i个数字的 a[0]-a[i]的最大子段和
    int n = 0; //记录到第几个数字
    int maxsum;
    c[0] = a[0];
    for (n = 1; n < len; n++)
    {
        c[n] = (c[n - 1] < 0) ? a[n] : c[n - 1] + a[n];
    }
    maxsum = c[n - 1];
    free(c);

    int tmpn = len - 1;
    while (a[tmpn] < 0)
    {
        maxsum -= a[tmpn];
        tmpn--;
    }
    
    return maxsum;

}

int main()
{
    int a[8] = {1, -2, 3, 10, -4, 7, 2, -5};
    int m = Max_Sum(a, 8);

    return 0;
}

 

网上有更加简化的版本:http://blog.sina.com.cn/s/blog_8b745a5f01014xur.html

没有必要存c的所有值,因为每次只用到了前一个值,再往前的都没有用了

#define max(a,b) ((a)>(b)?(a):(b))   //定义计算a,b两者中最大值的宏

int maxsum(int arr[],int num)
{
    int i;
    int maxsofar=0;       //maxsofar记录到目前为止的最大值
    int maxendinghere=0;//maxendinghere记录从当前位置开始往前几个连续的数的和的最大值(或0)
    for(i=0;i<num;i++)
    {
        maxendinghere=max(maxendinghere+arr[i],0);
        maxsofar=max(maxsofar,maxendinghere);
    }
    return maxsofar;
}

 

posted @ 2014-09-09 22:16  匡子语  阅读(532)  评论(0编辑  收藏  举报