1. 程式人生 > >最大子數組問題/Maximum Subarray

最大子數組問題/Maximum Subarray

std -s contain amp 方式 urn ber largest using

問題描述:

Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array [?2,1,?3,4,?1,2,1,?5,4],
the contiguous subarray [4,?1,2,1] has the largest sum = 6.

問題分析(參考了算法導論第4章分治策略的內容):

為求一個含負數的一組數種,和為最大的子數組
這裏使用分治的思想

首先,這一個子數組它只可能以3種方式存在:
完全在上半部分:low--mid
完全在下半部分:mid--high
或者跨越中點地存在:可理解為Arr[i..mid]+[mid+1..j]最大的元素和組成

算法的思想:遞歸地尋求左、右部分的最大子數組和
最後合並每次遞歸結果的解(只保留最後最大的結果)

時間復雜度分析:

n=1 T(1)=Θ(1)
n>1 子問題——求解左子數組和右子數組;每組子問題求解花費T(n/2)
所以算法的運行時間T(n)遞歸式為:
T(n)={ Θ(1) ,n=1
2T(n/2) ,n>1
最後可以求解出T(n)=Θ(nlgn)

 1 #include<iostream>
 2 #include<climits>
 3 using namespace std;
 4 const int infinite=-9999
; 5 int Find_Max_Crossing_Subarray(int arr[],int low,int mid,int high)//掃描上半部分最大和、下半部分最大和,上下部分結合為跨越中點最大和 6 { 7 8 int left_sum=infinite; 9 int right_sum=infinite; 10 int max_left=-1,max_right=-1,sum=0; 11 for(int i=mid; i>=low; i--) 12 { 13 sum+=arr[i]; 14 if(sum>left_sum)
15 { 16 left_sum=sum; 17 max_left=i; 18 } 19 } 20 sum=0; 21 for(int j=mid+1; j<=high; j++) 22 { 23 sum+=arr[j]; 24 if(sum>right_sum) 25 { 26 right_sum=sum; 27 max_right=j; 28 } 29 } 30 return (left_sum+right_sum); 31 } 32 int Find_Maximum_Subarray(int arr[],int low,int high)// 33 { 34 if(high==low)//只有一個元素的時候 35 return arr[low]; 36 else 37 { 38 int mid=(low+high)/2; 39 int leftSum=Find_Maximum_Subarray(arr,low,mid); 40 int rightSum=Find_Maximum_Subarray(arr,mid+1,high); 41 int crossSum=Find_Max_Crossing_Subarray(arr,low,mid,high); 42 if(leftSum>=rightSum&&leftSum>=crossSum) 43 return leftSum; 44 else if(rightSum>=leftSum&&rightSum>=crossSum) 45 return rightSum; 46 else return crossSum; 47 } 48 } 49 int main() 50 { 51 int arr[10]= {5,2,8,-6,9,1,10,7,-13,9}; 52 int ans=Find_Maximum_Subarray(arr,0,9); 53 cout<<ans<<endl; 54 return 0; 55 }

最大子數組問題/Maximum Subarray