程序员面试100题---3.求子数组的最大和

程序员面试100题---3.求子数组的最大和

问题描述:

输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。

例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10,-4, 7, 2,
因此输出为该子数组的和18。

问题分析:

解法1,直接法,设sum[i..j],为数组中第i到j之间所有数字的和,计算出所有的sum,再求其中最大的,时间复杂度为O(N^2)

int max_sum1(int a[],int n)
{
     if(!a || n < 0)
          exit(1);

     int max = -1;
     int i,j,sum;
     for(i = 0; i < n; i++)
     {
          sum = 0;
          for(j = i; j < n; j++)
          {
                sum += a[j];
                if(sum > max)
                   max = sum;
           }
 
      }
      return max;
}
此解法略微暴力,因此,性能较低。


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

解法2:

/*
    DP问题:
    假设我们已经知道(a[k].....a[n-1])最大的一段数组和为a[k],
    并且已经计算出在(a[k].....a[n-1])中包含A[k]的最大的一段数组和为Start[k],
    那么可以推断出All[k-1]=max{a[k-1],a[k-1]+Start[k],a[k]},
*/


int max_sum2(int a[], int n)
{
    int i;
    int nAll,nStart;
    if(!a || n < 0)
        exit(1);
    
    nAll = a[n-1];
    nStart = a[n-1];

    for(i = n - 2; i >= 0; i--)
    {
        nStart = max(a[i], a[i] + nStart);
        nAll = max(nAll,nStart);
    }

    return nAll;
}


你可能感兴趣的:(程序员面试100题精选,C语言)