这是我面试的时候想到的算法的实现,使用分治法,算法复杂度为O(n*log(n))。算法描述如下:
对于每一个划分子序列需要获取4个数值:
sum(子序列和)、maxSum(最大子序列和)、lMaxSum(最大的含有最左侧节点的子序列和)、rMaxSum(最大的含有最右侧节点的子序列和)
递归算法(res为需要运算的结果,lRes、rRes分别为该段的左右划分):
res->sum = lRes->sum + rRes->sum;
res->lMaxSum = max(lRes->lMaxSum, lRes->sum + rRes->lMaxSum);
res->rMaxSum = max(rRes->rMaxSum, rRes->sum + lRes->rMaxSum);
res->maxSum = max3(lRes->maxSum, rRes->maxSum, lRes->rMaxSum + rRes->lMaxSum);
全部源代码如下:
/**/
/*
* 子序列结果
*/
typedef
struct
_SubSequenceRes
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int sum;
int maxSum;
int lMaxSum;
int rMaxSum;
}
SubSequenceRes;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
/*
* 求两数中的最大值
*/
static
int
max(
int
m,
int
n)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
return (m>n) ? m : n;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
/*
* 求三数中的最大值
*/
static
int
max3(
int
a,
int
b,
int
c)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
return max(a, max(b, c));
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
/*
* 创建子序列结果结构
*/
static
SubSequenceRes
*
newSubSequenceRes()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
return (SubSequenceRes *)malloc(sizeof(SubSequenceRes));
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
/*
* 释放子序列结果结构
*/
static
void
deleteSubSequenceRes(SubSequenceRes
*
pointer)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
free(pointer);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
/*
* 循环解析子序列,获得子序列结果结构
*/
static
SubSequenceRes
*
_maxSubSequenceSum4(
int
a[],
int
left,
int
right)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int center;
int leftMaxSum;
int rightMaxSum;
SubSequenceRes *res = newSubSequenceRes();
SubSequenceRes *lRes, *rRes;
if (left == right)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
res->sum = res->maxSum = res->lMaxSum = res->rMaxSum = a[left];
}
else
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
center = (left + right) >> 1; /**//* center = (left + right) / 2; */
lRes = _maxSubSequenceSum4(a, left, center);
rRes = _maxSubSequenceSum4(a, center + 1, right);
res->sum = lRes->sum + rRes->sum;
res->lMaxSum = max(lRes->lMaxSum, lRes->sum + rRes->lMaxSum);
res->rMaxSum = max(rRes->rMaxSum, rRes->sum + lRes->rMaxSum);
res->maxSum = max3(lRes->maxSum, rRes->maxSum, lRes->rMaxSum + rRes->lMaxSum);
deleteSubSequenceRes(lRes);
deleteSubSequenceRes(rRes);
}
return res;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
/*
* 分治法实现:
* 对于每一个划分子序列需要获取4个数值:
* sum(子序列和)、maxSum(最大子序列和)、lMaxSum(最大的含有最左侧节点的子序列和)、rMaxSum(最大的含有最右侧节点的子序列和)
* 递归算法(res为需要运算的结果,lRes、rRes分别为该段的左右划分):
* res->sum = lRes->sum + rRes->sum;
* res->lMaxSum = max(lRes->lMaxSum, lRes->sum + rRes->lMaxSum);
* res->rMaxSum = max(rRes->rMaxSum, rRes->sum + lRes->rMaxSum);
* res->maxSum = max3(lRes->maxSum, rRes->maxSum, lRes->rMaxSum + rRes->lMaxSum);
*/
int
maxSubSequenceSum4(
int
a[],
int
len)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
SubSequenceRes * res = _maxSubSequenceSum4(a, 0, len - 1);
int result = res->maxSum;
deleteSubSequenceRes(res);
return result;
}