1. 请以伪代码描述最大子段和的分治算法
题目:给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时,定义子段和为0。
int max(int a[],int left,int right){//输入序列,头尾下标
int sum=0;
int a[MAX];
if(left==right){
sum=a[low]>0?a[high]:0;
}
else{//分治
int mid=(left+right)/2;
int leftsum=max(a,left,mid);//左段最大子段和
int rightsum=max(a,mid+1,right)//右段最大子段和
//最大子段和横跨左右两段,从中间往两边找最大子段和,加起来
int leftp=0;
int lefts=0;
for(int i=mid;i>=left;i--)//左部分最大子段和
{
lefts+=a[i];
if(lefts>leftp)
leftp=lefts;
}
int rightp=0;
int rights=0;
for(int i=mid+1;i<=right;i++)//右部分最大子段和
{
rights+=a[i];
if(rights>rightp)
rightp=rights;
}
}
sum=leftp+rightp;//加起来
sum=max(sum,leftsum,rightsum)//三种情况最大子段和
return sum;
}
2. 分析该算法的时间复杂度
划分子问题:时间复杂度为O(1)。 子问题为原问题的一半,2*T(n / 2)。
横跨左右数组找最大子段和:分别要n / 2次加法,O(n)。
合并子问题:横跨左右数组做n次加法,O(n)。
则T(n) = O(1) + 2 * T(n / 2) + O(n) = O(nlogn)。
3. 结合本章的学习,你对分治法的体会和思考
分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这箱子问题互相独立且与原问题相同。其实是递归思想。分解,处理好子问题后,将各个子问题的解合并得到原问题的解。