434
社区成员
发帖
与我相关
我的任务
分享1.请以伪代码描述最大字段和的分治算法
最大子段和的分治算法大致分为三种情况:
1.1最大字段和在左边 1.2最大字段和在右边 1.3最大字段和在中间
(1)临界情况:如果数组里面只有一个元素,若此元素大于0,则返回元素本身;反之,则返回0,代码如下
int MaxSum(int a, int left, int right){ //数组a,数组左下标left,数组右下标right
int sum = 0; //最大字段和
if(left == right) //序列长度为1的情况,如果为负数返回0,否则返回元素值
sum = a[left] > 0 ? a[left] : 0;
}
左边字段求和:
int s1 = 0; //记录左字段的最大字段和
int l = 0;
for(int i = mid; i >= left; i--){
l += a[i];
if(l >s1)
s1 = l;
}
右边字段求和:
int s2 = 0; //记录右边最大字段和
int r = 0;
for(int i = mid + 1; i <= right; i++){
r += a[i];
if(r > s2)
s2 = r;
}
最后分治法将三种情况比较。选择出最大字段和
sum = s1 + s2;
if(sum < leftsum)
sum = leftsum;
if(sum <rightsum)
sum = rightsum;
return sum;
2.分析该算法的时间复杂度
分解子问题的时候是直接分解,其时间复杂度为O(1),求解子问题的时候分成两段进行求解,每段长度是原来的一半,因此时间复杂度为2T(n/2),合并子问题算法时间复杂度为O(1)。再根据定理T(n)=2T(n/2)+O(n),所以得到最后的时间复杂度为O(nlogn).
3.结合本章的学习,你对分治法的体会和思考
分治法主要分为三个步骤:
将一个问题分解为多个相同类型的子问题;
求解这些子问题;
将子问题合并。
我们往往使用递归方法,直到递归结束条件,这个问题也被分解完成,之后开始不断返回。
分治法的应用场景十分广泛,汉诺塔、二分问题、排序等都会运用到分治法的思想。培养这种将大问题分解为小问题再合并解决的算法十分重要,我们应该熟练掌握。