这是我面试的时候想到的算法的实现,使用分治法,算法复杂度为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
... {
int sum;
int maxSum;
int lMaxSum;
int rMaxSum;
} SubSequenceRes;
/**/ /*
* 求两数中的最大值
*/
static int max( int m, int n)
... {
return (m>n) ? m : n;
}
/**/ /*
* 求三数中的最大值
*/
static int max3( int a, int b, int c)
... {
return max(a, max(b, c));
}
/**/ /*
* 创建子序列结果结构
*/
static SubSequenceRes * newSubSequenceRes()
... {
return (SubSequenceRes *)malloc(sizeof(SubSequenceRes));
}
/**/ /*
* 释放子序列结果结构
*/
static void deleteSubSequenceRes(SubSequenceRes * pointer)
... {
free(pointer);
}
/**/ /*
* 循环解析子序列,获得子序列结果结构
*/
static SubSequenceRes * _maxSubSequenceSum4( int a[], int left, int right)
... {
int center;
int leftMaxSum;
int rightMaxSum;
SubSequenceRes *res = newSubSequenceRes();
SubSequenceRes *lRes, *rRes;
if (left == right)
...{
res->sum = res->maxSum = res->lMaxSum = res->rMaxSum = a[left];
}
else
...{
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;
}
/**/ /*
* 分治法实现:
* 对于每一个划分子序列需要获取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)
... {
SubSequenceRes * res = _maxSubSequenceSum4(a, 0, len - 1);
int result = res->maxSum;
deleteSubSequenceRes(res);
return result;
}
* 子序列结果
*/
typedef struct _SubSequenceRes
... {
int sum;
int maxSum;
int lMaxSum;
int rMaxSum;
} SubSequenceRes;
/**/ /*
* 求两数中的最大值
*/
static int max( int m, int n)
... {
return (m>n) ? m : n;
}
/**/ /*
* 求三数中的最大值
*/
static int max3( int a, int b, int c)
... {
return max(a, max(b, c));
}
/**/ /*
* 创建子序列结果结构
*/
static SubSequenceRes * newSubSequenceRes()
... {
return (SubSequenceRes *)malloc(sizeof(SubSequenceRes));
}
/**/ /*
* 释放子序列结果结构
*/
static void deleteSubSequenceRes(SubSequenceRes * pointer)
... {
free(pointer);
}
/**/ /*
* 循环解析子序列,获得子序列结果结构
*/
static SubSequenceRes * _maxSubSequenceSum4( int a[], int left, int right)
... {
int center;
int leftMaxSum;
int rightMaxSum;
SubSequenceRes *res = newSubSequenceRes();
SubSequenceRes *lRes, *rRes;
if (left == right)
...{
res->sum = res->maxSum = res->lMaxSum = res->rMaxSum = a[left];
}
else
...{
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;
}
/**/ /*
* 分治法实现:
* 对于每一个划分子序列需要获取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)
... {
SubSequenceRes * res = _maxSubSequenceSum4(a, 0, len - 1);
int result = res->maxSum;
deleteSubSequenceRes(res);
return result;
}