434
社区成员
发帖
与我相关
我的任务
分享一、以伪代码描述最大字段和的分治算法
三种情况
1.最大字段在左边
2.最大字段在右边
3.最大字段在中间
int MaxSum(int a[ ], int left, int right)
{
int sum = 0;
if (left == right) //数组长度为一的情况
{
if (a[left] < 0) sum = 0;
}
else
{
int mid = (left + right) / 2;
int leftsum = MaxSum(a, left, mid);//数组左段和
int rightsum = MaxSum(a, mid + 1, right);//数组右段和
int S1 = 0;//左边最大字段和
int lefts = 0;
for (int i = mid; i >= left; i--)
{
lefts += a[i];
if (lefts > S1)
S1 = lefts;
}
int S2 = 0;//右边最大字段和
int rights = 0;
for (int i = mid + 1; i <= right; i++)
{
rights += a[i];
if (rights > S2)
S2 = rights;
}
sum = S1 + S2;//横跨中间最大字段和
if (sum < leftsum)
sum = leftsum;
if (sum < rightsum)
sum = rightsum;//找最大值
}
return sum;
}
二、分析时间复杂度
分解子问题:O(1)
求解子问题:2T(n/2)
合并子问题:O(n)
综合:O(nlogn)
三、对分治法的思考
分治法的主要步骤是,首先将求解较大规模的问题分割成k个更小规模的子问题,然后对这k个子问题分别求解,如果规模还不够小就继续往下划分,直到足够小易求得解,最后将子问题的解合并成为初始问题的解。
适用的条件:
1.问题的规模缩小到一定的程度就可以容易地解决;
2.问题可以分解为若干个规模较小的相同子问题;
3.问题分解出的子问题的解可以合并为该问题的解;
4.各个子问题是相互独立的,即子问题之间不包含公共的子问题。
这种拆分求解,用递归来实现可以让代码很简洁,让时间效率提高,但空间复杂度也比较高。