我们有一个数组,里面包含 10个元素:31,-41,59,26,-53,58,97,-93,-23,84 ,如何求出里面最大的连续子向量之和呢?
该程序应该输出下标为X[2,6]之间的和,187为最大。当所有数是正数的时候,问题很容易解决,但是如果包含了负数,可就难了。
有一个迭代算法,采用动态规划的思想:
maxsofar=0;
for(int i=0;i<n;i++)
{
sum=0;
for(j=i;j<n;j++)
{
sum+=x[i];
maxsofar=mas(maxsofar,sum);
}
}
这段代码的时间复杂度是 O(N*N)。
还有一个分治算法,可以将数组分为两半,然后继续分下去,最大值可能在左边一半,也可能是右边一半,也可能跨越左边右边。
float maxsum(l,u)
{
if(l>u) return 0;
if(l==u) return max(0,x[1]);
m=(l+u)/2;
lmax=sum=0;
for(i=m;i>=1;i--)
{
sum+=x[i];
lmax=max(lmax,sum);
}
rmax=sum=0;
for(i=m,u)
{
sum+=x[i];
rmax=max(rmax,sum);
}
return max(lmax+rmax,masum3(1,m),masum3(m+1,u));
这个算法代码比较复杂,但是时间复杂度降低了。
最后一个最重要的是扫描算法,这个算法很不好理解。下面给出伪代码如下:
maxsofar=0;
maxendinghere=0;
for i=0-n;
maxendinghere=max(maxendinghere+x[i],0);
maxsofar=max(maxsofar,maxendinghere);