您的位置:首页 > 编程语言 > Java开发

分治法求最大子序列和问题

2016-03-01 19:00 351 查看
求下面序列的最大子序列和:

4   -3    5     2    -1     2      6     -2

对于这个例子,最大子序列和可能在三处出现。

1.整个出现在输入数据的左半部。

2.整个出现在输出数据的右半部。

3.跨越输入数据的中部从而位于左右两半部分之中。

前两种情况可以递归求解。第三种情况的最大和可以通过求出前半部分(包含前半部分最后一个元素)的最大和以及后半部分(包含后半部分第一个元素)的最大和而得到。此时将这两个和相加。作为一个例子。考虑下列输出:

                             前半部分                                                          后半部分                             
             4            -2           5          -2            -1           2              6           -2
其中前半部分的最大子序列和为6(从元素A1到A3)而后半部分的最大子序列和为8(从元素A6到A7)。

前半部分包含其最后一个元素的最大和是4(从元素A1到A4),而后半部分包含其第一个元素的最大和是7(从元素A5到A7)。因此,横跨这两部分且通过中间的最大和为4+7=11(从A1到A7)。

代码如下:

public class Main {

public static void main(String[] args){
int a[]={4,-3,5,-2,-1,2,6,-2};
System.out.println(maxSumRec(a,0,a.length-1));
}

private static int maxSumRec(int[] a, int left, int right) {
if (left==right)
{
if (a[left]>0)
return a[left];
else
return 0;
}

int center = (left+right)/2;
int maxLeftSum = maxSumRec(a,left,center);
int maxRightSum = maxSumRec(a,center+1,right);

int maxLeftBorderSum=0,leftBorderSum=0;
for (int i = center;i>=left;i--)
{
leftBorderSum+=a[i];
if (leftBorderSum>maxLeftBorderSum)
{
maxLeftBorderSum=leftBorderSum;
}
}
int maxRightBorderSum=0,RightBorder=0;
for (int i = center+1;i<=right;i++)
{
RightBorder+=a[i];
if (RightBorder>maxRightBorderSum)
{
maxRightBorderSum=RightBorder;
}
}
return max3(maxLeftSum,maxRightSum,maxLeftBorderSum+maxRightBorderSum);
}

private static int max3(int num1,int num2,int num3) {
int max =0;
int temp1 = num1>num2?num1:num2;
max = temp1>num3?temp1:num3;
return max;
}

}

运行结果:

11

这个分治法我哥假期里面给我讲过一下原理,但是并不知道该如何去写代码。。。还是从书上看的,现在成功掌握了。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java java学习 博客