基本原理:最大字段有三种情况:1.最大字段在mid左边;2.最大字段在mid右边;3.最大字段经过mid
第三种情况经过mid时,只需要从mid开始分别往左右两端遍历数组,找到最大值返回即可
当最大字段在mid左边或者右边时,运用分治策略,把问题划分成更小的问题,递归解决。
代码实现如下
int FindMaxCrossingSubarray(int a[],int low,int mid,int high){
int leftsum=-99999,rightsum=-99999; //左右最大和设为无穷小
int sum=0;
for(int i=mid;i>=low;i--){ //左边最大和(包括mid)
sum=sum+a[i];
if(sum>leftsum)
leftsum=sum;
}
sum=0;
for(int j=mid+1;j<=high;j++){ //右边最大和
sum=sum+a[j];
if(sum>rightsum)
rightsum=sum;
}
return (leftsum+rightsum); //返回经过mid的最大子段和
}
int FindMaxSubarray(int a[],int low,int high){
if(high==low) //basecase 当只有一个元素时不再划分
return a[low];
else{
int mid=(low+high)/2;
int leftsum=FindMaxSubarray(a,low,mid);
int rightsum=FindMaxSubarray(a,mid+1,high);
int crosssum=FindMaxCrossingSubarray(a,low,mid,high);
if (leftsum>=rightsum&&leftsum>=crosssum)
return leftsum;
if(rightsum>=leftsum&&rightsum>=crosssum)
return rightsum;
if(crosssum>=leftsum&&crosssum>=rightsum)
return crosssum;
}
}