子數組最大和 動態規劃求解

     最近在看精選微軟等公司經典的算法面試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;
}

上述代碼完全個人創作,希望能對同道中人有所幫助!這也是個人將此學習筆記公佈的初衷!代碼如有不妥!望多指教!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章