问题描述:
给定由n个整数组成的序列(a1, a2, …, an),最大子段和问题要求该序列形如
的最大值(1≤i≤j≤n),当序列中所有整数均为负整数时,其最大子段和为0。例如,序列(-20, 11, -4, 13, -5, -2)的
最大子段和为:
最大子段和问题的分治策略是:
(1)划分:按照平衡子问题的原则,将序列(a1, a2, …, an)划分成长度相同的两个子序列
则会出现以下三种情况:
int MaxSum(int a[ ], int left, int right)
{
sum=0;
if (left= =right) { //如果序列长度为1,直接求解
if (a[left]>0) sum=a[left];
else sum=0;
}
else {
center=(left+right)/2; //划分
leftsum=MaxSum(a, left, center);
//对应情况①,递归求解
rightsum=MaxSum(a, center+1, right);
//对应情况②,递归求解
s1=0; lefts=0; //以下对应情况③,先求解s1
for (i=center; i>=left; i--)
{
lefts+=a[i];
if (lefts>s1) s1=lefts;
}
s2=0; rights=0; //再求解s2
for (j=center+1; j<=right; j++)
{
rights+=a[j];
if (rights>s2) s2=rights;
}
sum=s1+s2; //计算情况③的最大子段和
if (sum<leftsum) sum=leftsum;
//合并,在sum、leftsum和rightsum中取较大者
if (sum<rightsum) sum=rightsum;
}
return sum;
}
对应划分得到的情况①和②,需要分别递归求解,对应情况③,两个并列for循环的时间复杂性是O(n),所以,存在如下递推式:
算法的时间复杂性为O(nlog2n)。