问题描述:
有这么一个整数数组,A={13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};找出数组A的和最大的非空连续子数组。
限制条件:求出的子数组必须跨越中点。
分析:
假设求出的子数组是A[low…high]任何跨越终点的子数组都由两个子数组A[i…mid]和A[mid+1…j]组成,其中low<=i<=mid且mid<=j<=high。因此,我们只需找出形如A[i…mid]和A[mid+1…j]的最大子数组,然后将其合并即可。
代码如下
public static void main(String[] args) {
int[] an = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
int low = 0;
int high = an.length-1;
int[] result = find_maximum_subarray(an,low,high).clone();
System.out.println("数组起点坐标:"+result[0]+" ;\n终点坐标:"+result[1]+" ;\n最大子数组的和:"+result[2]);
}
public static int[] find_max_crossing_subarray(int[] an,int low,int mid,int high){
mid = an.length/2;
int left_sum = -99999;
int sum = 0;
int max_left=mid;
for(int i=mid-1;i>=0;i--){
sum+=an[i];
if(sum>left_sum){
left_sum = sum;
max_left = i;
}
}
int right_sum = -99999;
sum = 0;
int max_right=mid;
for(int i=mid;i<an.length;i++){
sum+=an[i];
if(sum>right_sum){
right_sum = sum;
max_right = i;
}
}
int result[] = {max_left,max_right,left_sum+right_sum};
return result;
}
public static int[] find_maximum_subarray(int[] an,int low,int high){
if(high==low){
int[] result = {low,high, an[low]};
return result;
}else{
int[] result=new int[4];
int mid = (low+high)/2;
int[] left_result = new int[3];
left_result = find_maximum_subarray(an,low,mid).clone();
int[] right_result = new int[3];
left_result = find_maximum_subarray(an,mid+1,high).clone();
int[] cross_result = new int[3];
cross_result = find_max_crossing_subarray(an,low,mid,high).clone();
if(left_result[2]>=right_result[2]&&left_result[2]>=cross_result[2]){
result[0] = left_result[0];
result[1] = left_result[1];
result[2] = left_result[2];
return result;
}else if(right_result[2]>=left_result[2]&&right_result[2]>=cross_result[2]){
result[0] = right_result[0];
result[1] = right_result[1];
result[2] = right_result[2];
return result;
}
else{
result[0] = cross_result[0];
result[1] = cross_result[1];
result[2] = cross_result[2];
return result;
}
}
}