package divide.conquer;
public class MaximumSubarray {
/*n*lg(n)
* */
public static void main(String[] args) {
int[] A=new int[] {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
ReturnValues returnValues=new MaximumSubarray().find_maximun_subarray(A, 0, A.length-1);
System.out.println(returnValues);
}
public ReturnValues find_maximun_subarray(int A[],int low,int high) {
if(high==low) {
return new ReturnValues(low,high,A[high]);
}else {
int mid=(low+high)/2;
ReturnValues returnValues_left=new ReturnValues();
returnValues_left=find_maximun_subarray(A,low,mid);
ReturnValues returnValues_right=new ReturnValues();
returnValues_right=find_maximun_subarray(A,mid+1,high);
ReturnValues returnValues_cross=new ReturnValues();
returnValues_cross=find_max_crossing_subarray(A,low,mid,high);
//求解出三段结果,比较求出最大的一段
if(returnValues_left.sum>=returnValues_right.sum&&
returnValues_left.sum>=returnValues_cross.sum) {
return returnValues_left;
}else if(returnValues_right.sum<=returnValues_left.sum&&
returnValues_right.sum>=returnValues_cross.sum) {
return returnValues_right;
}else {
return returnValues_cross;
}
}
}
//寻找左边和右边包括中间数组在内的最大字串
public ReturnValues find_max_crossing_subarray(int A[],int low,int mid,int high) {
int left_sum=-9999;
int sum=0;
int max_left=mid;
int right_sum=-9999;
int max_right=mid;
for(int i=mid;i>=low;i--) {
sum=sum+A[i];
if(sum>left_sum) {
left_sum=sum;
max_left=i;
}
}
sum=0;
for(int j=mid+1;j<=high;j++) {
sum=sum+A[j];
if(sum>right_sum) {
right_sum=sum;
max_right=j;
}
}
ReturnValues returnValues=new ReturnValues(max_left,max_right,left_sum+right_sum);
return returnValues;
}
}
//存放返回值
class ReturnValues{
int max_left;
int max_right;
int sum;
public ReturnValues(int max_left, int max_right, int sum) {
super();
this.max_left = max_left;
this.max_right = max_right;
this.sum = sum;
}
public ReturnValues() {
super();
}
@Override
public String toString() {
return "ReturnValues [max_left=" + max_left + ", max_right=" + max_right + ", sum=" + sum + "]";
}
}
测试结果:
ReturnValues [max_left=7, max_right=10, sum=43]