分析
这里我们以数组 arr[]={-20,11,-4,13,-5,-2}; 为例
求子区间及最大和,从结构上是非常适合分治法的,因为所有子区间[start, end]只可能有以下三种可能性:
在[0, (arr.length-1)/2]这个区域内
在[(arr.length-1)/2+1, arr.length-1]这个区域内
起点位于[0, (arr.length-1)/2],终点位于[(arr.length-1)/2+1, arr.length-1]内
以上三种情形的最大者,即为所求. 前两种情形符合子问题递归特性,所以递归可以求出. 对于第三种情形,则需要单独处理. 第三种情形必然包括了 (arr.length-1)/2 和 (arr.length-1)/2+1 两个位置,这样就可以利用第二种穷举的思路求出:
1. 以(arr.length-1)/2为终点,往左移动扩张,求出和最大的一个leftSum
2. 以(arr.length-1)/2+1为起点,往右移动扩张,求出和最大的一个rightSum
3. leftSum+rightSum=midSum midSum是第三种情况可能的最大值
//最大子段 public class Maxsize { public static void main(String[] args) { int arr[]={-20,11,-4,13,-5,-2}; System.out.println(maxsize(arr,0,arr.length-1)); } public static int maxsize(int[] arr, int left, int right){ int sum=0,midSum=0,leftSum=0,rightSum=0; int center,s1,s2,lefts,rights; //如果序列长度为1时 if (left==right){ sum=arr[left]; } else { //划分 center=(left+right)/2; //左递归 leftSum=maxsize(arr,left,center); //又递归 rightSum=maxsize(arr,center+1,right); s1=0;lefts=0; for (int i=center;i>=left;i--){ lefts+=arr[i]; if (lefts>s1){ s1=lefts; } } s2=0;rights=0; for (int j=center+1;j<=right;j++){ rights+=arr[j]; if (rights>s2){ s2=rights; } } midSum=s1+s2; if (midSum<leftSum){ sum=leftSum; } else { sum=midSum; } if (sum<rightSum){ sum=rightSum; } } return sum; } }