一、问题描述
给定一个有n(n >= 1)个整数的序列,求出其中最大连续子序列的和。例如序列(34,-20,30,-50,60,-20,30,41,-30,-10)最大子序列和为111,序列(-2,11,-4,13,-5,-2)最大子序列和为20。规定一个序列的最大连续子序列和至少为0。
二、问题求解
1、对于含有n个整数的序列,若n=1,表示序列仅有一个元素,该元素大于0,则返回该元素,否则返回0。
if(left == right){
if(a[left]>=0)
return a[left];
else
return 0;
}
2、如果n>1,则采用分治法求解最大连续子序列和。取中间位置 mid = ( left + right ) /2 。则最大连续子序列和只可能出现在3个地方。
- ①该子序列全部落在左半部分,即a[0,···mid]中,该问题和原本问题解决方法一样,采用递归求出其最大连续子序列和maxLeftSum。
- ②该子序列全部落在右半部分,即a[mid+1,···n-1]中,该问题和原本问题解决方法一样,采用递归求出其最大连续子序列和maxRightSum。
- ③该子序列跨越序列a的中部而占据左右两部分。也就是说,这种情况下的最大连续子序列和必然包括mid元素,则先求出maxLeftBorderSum,从mid(终点)到left的最大连续子序列和,找到左边最大连续子序列和的起点位置,将左边到mid的最大连续子序列和赋值给maxLeftBorderSum。再求出maxRightBorderSum,从mid(起点)到right的最大连续子序列和,找到右边最大连续子序列和的终点位置,将mid到右边的最大连续子序列和赋值给maxRightBorderSum。这种情况下的最大连续子序列和为 maxMidSum =maxLeftBorderSum+maxRightBorderSum
3、整个序列a的最大连续子序列和为maxMidSum 、maxLeftBorderSum、maxRightBorderSum。将三者进行大小比较即为最终结果。
三、完整代码展示(C语言)
//求解最大连续子序列和问题
#include<stdio.h>
int num[10] = {34,-20,30,-50,60,-20,30,41,-30,-10};
//int num[6] = {-2,11,-4,13,-5,-2};
int max3(int a,int b,int c){ //求三者的最大值
if(a < b)
a = b;
if(a < c)
a = c;
return a;
}
int maxSubSum(int a[],int left,int right){
int i,j;
int maxLeftSum,maxRightSum;
int maxLeftBorderSum,leftBorderSum;
int maxRightBorderSum,rightBorderSum;
if(left == right){ //只有一个元素的情况
if(a[left]>=0)
return a[left];
else
return 0;
}
int mid = (left+right)/2; //取中间位置
maxLeftSum = maxSubSum(a,left,mid); //求左边的最大序列和
maxRightSum = maxSubSum(a,mid+1,right); //求右边的最大序列和
maxLeftBorderSum = 0;
leftBorderSum = 0;
maxRightBorderSum = 0;
rightBorderSum = 0;
//最大连续子序列在序列a的中部而占据左右两部分情况
for(i=mid;i>=left;i--){ //求mid到左边的maxLeftBorderSum
leftBorderSum += a[i];
if(maxLeftBorderSum < leftBorderSum)
maxLeftBorderSum = leftBorderSum;
}
for(j=mid+1;j <= right;j++){ //求mid到右边的maxRightBorderSum
rightBorderSum += a[j];
if(maxRightBorderSum < rightBorderSum)
maxRightBorderSum = rightBorderSum;
}
return max3(maxRightBorderSum,maxLeftBorderSum,maxLeftBorderSum+maxRightBorderSum);
}
int main(){
printf("maxSubSum= %d\n",maxSubSum(num,0,9));
return 0;
}