最大子数组的定义是在一个数组中和为最大的连续非空子数组
而最简单的解法为暴力枚举,如下FIND-MAX-GROSSING-SUBARRAY(A) declare SUM as the sum of subarray for i = 1 to A.length SUM[i] = 0 for j = i to A.lenth SUM[i] += A[j] retrun MAX(SUM)
其时间复杂度为 O(n*n)
但是可以通过分治策略将该问题划分成三个子问题——左边最大子树组问题、
右边最大子树组问题以及跨过中点的最大子树组问题.
而后最大的数则为该数组的最大子数组的结果。
其时间复杂度为 O(n * lg n)。FIND-MAXIMUM-SUBARRAY(A,left,right) if left == right return (left, right, A[left]) else mid = (left+right)/2 return subarrayMax( FIND-MAXIMUM-SUBARRAY(A,left,mid), FIND-MAXIMUM-SUBARRAY(A,mid+1,right), FIND-MAX-GROSSING-SUBARRAY(A,left,mid,right) ) FIND-MAX-GROSSING-SUBARRAY(A,left,mid,right) left-sum = - INF sum = 0 for i = mid downto l sum += A[i] if sum > left-sum left-sum = sum max-left = i right-sum = -INF sum = 0 for i = mid + 1 to r sum += A[i] if sum > right-sum right-sum = sum max-right = i return (max-left, max-right, left-sum + right-sum )
其实现代码如下
# define INF 0x3f3f3f3f
struct Subarray
{
int left;
int right;
int sum;
Subarray(){}
Subarray(int left,int right,int sum)
{
this->left = left;
this->right = right;
this->sum = sum;
}
};
Subarray subarrayMax(Subarray a, Subarray b)
{
return a.sum > b.sum ? a:b;
}
Subarray subarrayMax(Subarray left, Subarray right, Subarray mid)
{
return subarrayMax(subarrayMax(left,right), mid);
}
Subarray findMaxGrossingSubarray(int *arrayA,int left,int mid,int right)
{
int sum = 0;
int leftSum = - INF;
int maxLeft = mid;
for(int i=mid;i>=0;--i){
sum += arrayA[i];
if(sum > leftSum){
leftSum = sum;
maxLeft = i;
}
}
sum = 0;
int rightSum = - INF;
int maxRight = mid + 1;
for(int j=mid+1;j<=right;++j){
sum += arrayA[j];
if(sum > rightSum){
rightSum = sum;
maxRight = j;
}
}
return Subarray(maxLeft, maxRight, leftSum + rightSum );
}
Subarray findMaximumSubarray(int *arrayA,int left,int right)
{
if(left == right )
return Subarray(left,right,arrayA[left]);
int mid = (left + right) / 2;
Subarray maxSubarray;
return subarrayMax(findMaximumSubarray(arrayA, left, mid),
findMaximumSubarray(arrayA, mid + 1, right),
findMaxGrossingSubarray(arrayA, left, mid, right) );
}