您的位置:首页 > 职场人生

面试题31.连续子数组的最大和

2015-09-01 15:45 537 查看
题目:输入一个整型数组,数组里有正数也有负数。数组中一个或者连续多个整数组成一个子数组。

求所有子数组的和的最大值。要求时间复杂度O(n)

本题可以把所有子数组全部找出来再求其和的最大值便可以得出,但是这样会导致算法的时间复杂度

为0(n^2),所以有两种方法来解决这个问题。

方法1.数组扫描

我们扫描一遍数组并且累加数组元素的和,当遇到累加和为负数的时候,我们从数组中

下一个元素开始重新累加。直到遍历完成。

方法2.动态规划的方法

有这样一个公式

  { pdata[i] if f(i-1)<=0

f(i){

{f(x-i)+pdata[i] if f(i-1)>0

怎么理解呢,f(i)是一个数组,其代表数组中第1-i个子数组的最大和,当f(i-1)为负的时候,此时加上一个pdata[i]会更小

所以f(i)=pdata[i]

当f(i-1)为正的时候,此时加上一个pdata[i]会更大,所以f(i)=f(i-1)+pdata[i];

下面我们分别实现两种方法:

第一种扫描法(如果只想找最大的则不必找出最大子数组到底是哪些元素,复杂度0(n))

#include <iostream>
using namespace std;

int FindSerialMaxSum(int* pData,int nLength)
{
int CurrSum=0;
int MaxSum=0;

if(pData==NULL||nLength==0)
return 0;
int *ChildArray=new int[nLength];
for(int k=0;k<nLength;k++)
ChildArray[k]=0;

int index=0;

for(int i=0;i<nLength;i++)
{
if(CurrSum<=0)
{
CurrSum=pData[i];
for(int j=0;j<nLength;j++)
ChildArray[j]=0;
index=0;
ChildArray[index]=pData[i];
}
else
{
CurrSum+=pData[i];
index++;
ChildArray[index]=pData[i];
}

if(CurrSum>MaxSum)
MaxSum=CurrSum;
}

int Temp=0;
cout<<"The Child Array is : ";
for(int l=0;pData[l]!=0;l++)
{
if(Temp==MaxSum)
{
break;
}
Temp+=ChildArray[l];
cout<<ChildArray[l]<<" ";
}
cout<<endl;

return MaxSum;
}

int main(int argc ,char* argv[])
{
int pdata[]={1,-2,3,10,-4,7,2,-5};
int nLength=8;
int SerivalSum=FindSerialMaxSum(pdata,nLength);
if(SerivalSum!=0)
cout<<"The Serial Max Sum = "<<SerivalSum<<endl;
else
cout<<"Input error!"<<endl;
system("pause");
return 0;
}


运行结果:



2.动态规划的方法(f(i)为存储0-i子数组的最大和)

#include <iostream>
using namespace std;

int FindSerialMaxSum(int* pData,int nLength,int* f)
{
f[0]=pData[0];
int MaxSum=0;
for(int i=1;i<nLength;i++)
{
if(f[i-1]<=0)
{
f[i]=pData[i];
}
else
{
f[i]=f[i-1]+pData[i];
}

if(f[i]>MaxSum)
MaxSum=f[i];
}
for(int k=0;k<nLength;k++)
{
cout<<f[k]<<" ";
}
cout<<endl;
return MaxSum;
}

int main(int argc ,char* argv[])
{
int pdata[]={1,-2,3,10,-4,7,2,-5};
int nLength=8;
int *f=new int[nLength];
int SerivalSum=FindSerialMaxSum(pdata,nLength,f);
if(SerivalSum!=0)
cout<<"The Serial Max Sum = "<<SerivalSum<<endl;
else
cout<<"Input error!"<<endl;
delete[] f;
system("pause");
return 0;
}


运行截图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: