最近在看精選微軟等公司經典的算法面試100題裏面的第三題,求最大子數組和,具體問題如下:
題目:
輸入一個整形數組,數組裏有正數也有負數。
數組中連續的一個或多個整數組成一個子數組,每個子數組都有一個和。
求所有子數組的和的最大值。要求時間複雜度爲O(n)。
例如輸入的數組爲1, -2, 3, 10, -4, 7, 2, -5,和最大的子數組爲3, 10, -4, 7, 2,
因此輸出爲該子數組的和18。
自己的求解思路如下:(可以直接調試運行)
#include<iostream>
#include<vector>
using namespace std;
//解法一:複雜度O(n*n)
//可用循環計算子數組最大和。
int MaxSubArry(const vector<int> data)
{
int max=-99999,i,j,sum=0;
for(i=0;i<data.size();i++)
{
sum=0;
for(j=i;j<data.size();j++)
{
sum+=data[j];
if(sum>max)
max=sum;
}
}
return max;
}
//方法二:複雜度O(n)
//問題描述符合動態規劃最優子結構的要求。
//設b[i]表示以a[i]結尾 的子數組的最大子段和,即:
//b[i]=max{sum(a[j~k])},其中0<=j<=i,j<=k<=i。
//因此對於數組a[0~n]的最大字段和爲max{b[i]},其中0<=i<n。
//在計算b[i]時,可以考慮以下三種情況:
//1,b[i] = b[i-1]+a[i],當b[i-1]>0時,這時候的b[i]中包含a[i]。
//2,b[i] = a[i],當b[i-1]<=0,這時候以a[i]重新作爲b[i]的起點。
//3,b[i]不包含a[i]的情況,這種情況在計算b[i]之前已經計算處結果,保存在b[0~i-1]中。最後計算max{b[i]}時會考慮到。
//b[i] = max{ b[i-1]+a[i],a[i]}。
//而數組a[0~n]則爲max{b[i]}。
//本人認爲方法二的基本原理是:
//一個數加非負數大於等於其本身。a+x>=a{其中a爲常數,x>=0}
int max_sub_arry(const vector<int> data,int& start,int& end)
{
int i,b=data[0],sum=data[0],s=0,e=0;
for(i=1;i<data.size();i++)
{
if(b>0)
{
b+=data[i];
e=i;
}
else
{
b=data[i];
s=e=i;
}
if(sum<b)
{
sum=b;
start=s;
end=e;
}
}
return sum;
}
int main()
{
vector<int> data;
int x;
cout<<"please input array ,and use 0 end input."<<endl;
cin>>x;
while(x!=0)
{
data.push_back(x);
cin>>x;
}
cout<<"the max sum length of data is :"<<MaxSubArry(data)<<endl;
int start=0,end=0;
cout<<endl<<"the max sum of sub array is :"<<max_sub_arry(data,start,end)<<endl<<endl<<"and this sub array is :"<<endl;
for(int i=start;i<=end;i++)
{
cout<<data[i]<<"\t";
}
cout<<endl;
system("pause");
return EXIT_SUCCESS;
}
上述代碼完全個人創作,希望能對同道中人有所幫助!這也是個人將此學習筆記公佈的初衷!代碼如有不妥!望多指教!