本题源自编程之美,也是2006年微软亚研院的笔试题,下面分别给出一般思路和最优思路及其代码
一般思路:由于sum(a[0],a[1],……,a[n-1],a[n])=sum(a[0],a[1],……a[n-1])+a[n],那么我们对可能存在的每一个字数组进行扫描即可,该算法的时间复杂度是O(N*N),另外一种基于分治的方法时间复杂度为O(N*logN),这里不再赘述,详见数据结构与算法分析19-20页.
int maxsum(const int a[],int n)
{
int ThisSum,MaxSum,i,j;
MaxSum=0;
for(i=0;i<n;i++)
{
ThisSum=0;
for(j=i;j<n;j++)
{
ThisSum+=a[j];
if(ThisSum>MaxSum)
MaxSum=ThisSum;
}
}
return MaxSum;
}
最优思路:用sum保存当前的计算值,用max保存最终的最大值。那么从数组的第一个元素向后扫描,当sum>0时则继续累加,当sum<0时则抛弃前面所有的数,扫描过程中发现sum>max,则将其值赋给max,算法如下:
int maxSum(int a[n])
{
int max=a[0]; //全负情况,返回0
int sum=0;
for(int j=0;j<n;j++)
{
if(sum>=0) //如果加上某个元素,sum>=0的话,就加
sum+=a[j];
else
sum=a[j]; //如果加上某个元素,sum<0了,就不加了
if(sum>max)
max=sum; //sum存放的是前一刻的最大值
}
return max;
}
完整测试代码如下:
#include <iostream>
using namespace std;
int maxsum(const int a[],int n)
{
int ThisSum,MaxSum,i,j;
MaxSum=0;
for(i=0;i<n;i++)
{
ThisSum=0;
for(j=i;j<n;j++)
{
ThisSum+=a[j];
if(ThisSum>MaxSum)
MaxSum=ThisSum;
}
}
return MaxSum;
}
int maxSum(int a[],int n)
{
int max=a[0]; //全负情况,返回0
int sum=0;
for(int j=0;j<n;j++)
{
if(sum>=0) //如果加上某个元素,sum>=0的话,就加
sum+=a[j];
else
sum=a[j]; //如果加上某个元素,sum<0了,就不加了
if(sum>max)
max=sum; //sum存放的是前一刻的最大值
}
return max;
}
int main()
{
int a[10]={-2,-4,-5-2};
cout<<maxSum(a,4)<<endl;
cout<<maxsum(a,4)<<endl;
system("pause");
return 0;
}