package maxZiArray;
import java.util.Arrays;
public class ChildArray {
/*
* 用于发现最大子数组 ——分治策略
* param b[] 需要求解的数组
*
* @param first 数组的开始位置
*
* @param last 数组的结束位置
*
* @return 所求子数组
*/
public static SubArray findMaxChildSubArray(int[] b,int first,int last){
if(first == last){
return new SubArray(first,last,b[first]);
}
else{
int mid = (first + last) / 2;
SubArray subArrayLeft = findMaxChildSubArray(b, first, mid);
SubArray subArrayRight = findMaxChildSubArray(b, mid+1, last);
SubArray subArrayCross = findMaxCrossSubArray(b,first,mid,last);
if(subArrayLeft.getSum() > subArrayRight.getSum() && subArrayLeft.getSum() > subArrayCross.getSum()){
return subArrayLeft;
}
else if(subArrayRight.getSum() > subArrayLeft.getSum() && subArrayRight.getSum() > subArrayCross.getSum()){
return subArrayRight;
}
else{
return subArrayCross;
}
}
}
/*
* 用于求解跨界子数组的最大数组
*
* param b[] 需要求解的数组
*
* @param first 数组的开始位置
*
* @param mid 数组的分开位置
*
* @param last 数组的结束位置
*
* @return 所求子数组
*/
public static SubArray findMaxCrossSubArray(int[] b,int first,int mid,int last){
int leftsum = 0;
int leftindex = mid;
int sum = 0;
for (int i = mid; i >= 0; i--) { //注意边界问题,i是可以取到0的
sum += b[i];
if(sum > leftsum){
leftsum = sum;
leftindex = i;
}
}
int rightsum = 0;
int rightindex = mid+1;
sum = 0;
for (int i = mid + 1; i <= last; i++) { //注意边界问题,i 是可以取到last的,因为加入最后一项是b.length - 1;
sum += b[i];
if(sum > rightsum){
rightsum = sum;
rightindex = i;
}
}
return new SubArray(leftindex, rightindex, leftsum + rightsum);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] b = {3,4,-1,5,-6,9,8,-4,-7,5,-9};
// int[] b = {-4,5,6,6,3,7,3,2,5,6};
//为什么不能添加b.length,而非要添加b.length - 1;是以为在findMaxChildSubArray中当last==first是,无法取到b.length这个下标的值,以为是空,
// 这是会出现超出边界错误!
SubArray subArray = findMaxChildSubArray(b,0,b.length -1);
System.out.println("the orient array id" + Arrays.toString(b));
System.out.println("the max child Array is :");
for (int i = subArray.getLow(); i <= subArray.getHigh(); i++) {
System.out.print(b[i] + " ");
}
System.out.println("");
System.out.println(subArray.getLow() + " "+ subArray.getHigh() +" "+ subArray.getSum() + " " + subArray.getClass());
}
}
/*
* @param low 子数组的开始位置
*
* @param high 子数组的结束位置
*
* @param sum 子数组的和
*/
class SubArray{
private int low;
private int high;
private int sum;
public SubArray(int low, int high, int sum) {
super();
this.low = low;
this.high = high;
this.sum = sum;
}
和为k的最长连续子数组, public int getLow() {
return low;
}
public int getHigh() {
return high;
}
public int getSum() {
return sum;
}
}