分治算法-java求最大子数组问题

今天看算法导论的时候,就想着动纸和笔来思考分治算法求最大子数组的方案

首先我们分析问题,我们把数组看成 a [ low, high] ,将要用分治法求出其最大的子数组,用分治法相当于我们要把数组分成两个规模尽量相等的子数组 (因为有时候数组长度是奇数,无法区分),找到数组的中间位置mid,这样最大值出现的可能情况分为以下三种,

a [low ,mid ] , a[mid + 1 , high], a[i ,j ](low <= i <= j <high),第三种情况属于跨越了中点。

1 、完全位于子数组A[low..mid]中,low<=i<=j<=mid
2、 完全位于子数组A[mid+1..high]中,mid<i<=j<=high

3 、跨越了中点,因此low<=i<=mid<j<=high

那么可以用递归的求解a[low high]的最大子数组, 分为 a[ low, mid] ,a[ mid+1, high]的问题,只不过分治法,先将其分解成更小的,然后再合并出来。剩下的过程就是找最大子数组,然后在上面三种情况中找取最大值。


以下是我java实现的思路。

package cn.com.divideArithmatic;


/**
 * 求最大子数组
 * @author Administrator
 *
 */
public class MaxSonArr2 {
public static void main(String[] args) {
        int[] array = {6,5,8,-10,-3,2,7,-15};
int[] s = getMaxSummary(array,0,array.length-1);
for (int i = 0; i < s.length; i++) {
System.out.println(s[i]);
}
}
 

public static int[] getMaxSummary(int[] a, int low, int high) {
//获取数组的三个元素
if(high == low) {
int[] result = {low,high,a[low]};
return result;
}else{
//获取中心值
int mid = (low + high) / 2;
//创建保存结果的数组 arr[0] left arr[1] right arr[2]最大值
int[] left = new int[3]; // 保存左边部分返回结果
int[] right = new int[3]; // 保存右边部分返回结果
int[] cross = new int[3]; // 返回交叉部分返回结果
//递归获取值
left = getMaxSummary(a,low,mid);
right = getMaxSummary(a,mid+1,high);
//获取穿越中间的值
cross = getMaxCrossMid(a,low,high,mid);
//根据左 右 穿越中间的最大值返回结果
if(left[2] >= right[2] && left[2] >= cross[2]) {
return left;
}else if(right[2] >= left[2] && right[2] >= cross[2]) {
return right;
}else{
return cross;
}
}
}
 

public static int[] getMaxCrossMid(int[] a, int low, int high, int mid) {
int sum = 0;
//左边的最大值
int leftSum = 0;
//结果起始点位置
int left = 0;
//注意要判断最大值,要从中间往左取,这样穿越中间的值才能取最大
for (int i = mid; i >=low; i--) {
sum += a[i];
if(sum > leftSum) {
leftSum = sum;
left = i;
}
}
//相比左边就要 从中间往右边取
int rightSum = 0;
int right = 0;
sum = 0;
for (int i = mid + 1; i <= high; i++) {
sum += a[i];
if(sum > rightSum) {
rightSum = sum;
right = i;
}
}

//创建结果数组
int[] result = new int[3];
result[0] = left;
result[1] = right;
result[2] = leftSum + rightSum;
return result;
}

}

猜你喜欢

转载自blog.csdn.net/Dalton2017/article/details/81003581