程序员面试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;
}