1. 程式人生 > >分治——最大數組和

分治——最大數組和

窮舉 元素 sub cnblogs ++ 最大子數組和 分割 end 復雜度

問題描述:

給一個整數數組,求其所有子數組中和最大的子數組在所給整數數組的的起始位置與終點;

方法一:窮舉每個子數組,時間復雜度為o(N2);

方法三:時間復雜度為O(N); 請自行查閱書籍;

方法二:

  采用分治思想:

    先將數組從中間(分割點)分成兩部分(和最大子數組要麽在其左邊,要麽在其右邊,或者跨過分割點),先求出左邊和最大的子數組,再求右邊和最大的子數組,

    然後求經過中間分隔點的最大子數組和

    

 1 #include<iostream>
 2 using namespace std; 
 3 struct sub{      //定義一個子數組起點,終點與其所有元素和
4 int start; 5 int end; 6 7 int sum; 8 }; 9 10 sub merge(sub sub1,int start,int end,int A[]) // 11 { 12 int leftSum=0,rightSum=0,leftPos=(start+end)/2,rightPos=(start+end)/2+1,leftMax=-10000,rightMax=-10000; 13 14 for(int i=(start+end)/2;i>=start;i--) 15 { 16 leftSum+=A[i]; //
求最大數組和的起點 17 if(leftMax<leftSum) 18 { 19 leftPos=i; 20 leftMax=leftSum; 21 } 22 } 23 24 for(int i=(start+end)/2;i<=end;i++) 25 { 26 rightSum+=A[i]; 27 if(rightMax<rightSum) //求最大數組和的終點 28 { 29
rightPos=i; 30 rightMax=rightSum; 31 } 32 } 33 34 if ( sub1.sum< (rightMax+leftMax) ) 35 { 36 sub1.start=leftPos; 37 sub1.end=rightPos; 38 sub1.sum= (rightMax+leftMax); 39 } 40 41 return sub1; 42 } 43 sub recursion(int start,int end,int A[]) 44 { 45 sub sub1,sub2; 46 47 if(start<end) 48 { 49 sub1=recursion(start,(start+end)/2,A); 50 sub2=recursion((start+end)/2+1,end,A); 51 52 sub1=sub1.sum>sub2.sum?sub1:sub2; 53 54 return merge(sub1,start,end,A); 55 } 56 57 sub1.start=sub1.end=start; 58 sub1.sum=A[start]; 59 60 return sub1; 61 } 62 int main() 63 { 64 int a[]={1,-5,9,8,-3,-6,11}; 65 66 sub sub1=recursion(0,6,a); 67 68 cout<<sub1.start<<" to "<<sub1.end<<" sum:"<<sub1.sum<<endl; 69 70 } 71

分治——最大數組和