分治策略思想:将一个问题拆解成n个子问题,子问题互相独立,称为“分”;
对这些子问题递归求解,最后合并得到原问题的解称为“治”;
(如二分查找,快速排序,归并排序基本思想都是分治思想)
例:求解数组中的最大子序列。
5 | -3 | 5 | -1 | 2 | -4 | 6 | -2 |
解决思想:
对于该数组的最大值,可能出现在左半侧,右半侧,或者穿越中间位置分布在左右两侧。那么将数组平分为两份,左半部分且包括A[3]位置的最大子序列都为6(A[0]~A[3]),不包括A[3]的最大子序列为7(A[0]~A[2])。右半部分且包括A[4]位置的最大子序列为4,不包括A[4]的最大子序列为6(A[6])。将子解合并分析比较可得数组的最大子序列为10。
以下为程序实现,同时利用分治策略体现高性能的递归算法;
/**
*求解数组的最大子序列;
*arrs 被处理数组;
*left 数组的左边界;
*right 数组的右边界;
*return 最大子序列的值;
**/
public int getMaxSonSum(int[] arrs,int left,int right){
//当数组只有一个元素时,直接返回非零值;
if(left==right)
if(arrs[left]>0)
return arrs[left];
else
return 0;
//中间索引;
int center = (left+right)>>1;
//递归调用;
int maxLeftSum = getMaxSonSum(arrs,left,center);
int maxRightSum = getMaxSonSum(arrs,center+1,right);
//计算两侧包含中间索引的最大子序列的值;
//左侧;
int maxLeftBorderSum =0,leftBorderSum = 0;
for(int i=center;i>=left;i--){
leftBorderSum += arrs[i];
if(leftBorderSum > maxLeftBorderSum)
maxLeftBorderSum = leftBorderSuM;
}
//右侧;
int maxRightBorderSum =0,rightBorderSum = 0;
for(int i = center+1;i<=right;i++){
rightBorderSum += arrs[i];
if(rightBorderSum>maxRightBorderSum)
maxRightBorderSum = rightBorderSum;
}
//比较三个子解的值,返回即最大子序列的值;
int maxSonSum = MATH.mx(MATH.max(maxLeftSum,maxRightSum),
maxLeftBorderSum+maxRightBorderSum)
return maxSonSum;
}
传入{5,-3,5,-1,2,-4,6,-2}可得到返回值为10(A[0]~A[6])。