最大子序列问题
- 穷举法:
/**
* 求最大子序列...
* 1.穷举法
* test
*/
public void test_1(){
int [] a = new int[10];
int maxSum = 0;
for(int i = 0; i < a.length ; i++){
for(int j = i; j < a.length;j++){
int thisSum = 0;
for(int k = i;k < j;k++)
thisSum += a[k];
if(thisSum > maxSum)
maxSum = thisSum;
}
}
}
2. 计算所有的序列和.得到其中最大的.
public void test_2(){
int a[] = new int[20];
int maxSum = 0;
for (int i = 0; i < a.length; i++) {
int thisSum = 0;
for(int j = i;j<a.length;j++){
thisSum += a[j];
if(thisSum > maxSum)
maxSum = thisSum;
}
}
}
3.使用递归进行计算.
①.先计算前半部分包含最后一个元素的最大序列.
②.再计算后半部分包含第一个元素的最大序列.
③.将两者相加即是数组的最大序列和.
②.再计算后半部分包含第一个元素的最大序列.
③.将两者相加即是数组的最大序列和.
public int maxSumRec(int [] a,int left,int right){
if(left == right)
if(a[left] > 0)
return a[left];
else
return 0;
int center = (left + right) / 2;
/*
* 得到左侧的最大序列和,可能不包含左侧的最后一个元素....
*/
int maxLeftSum = maxSumRec(a, left, center);
/**
* 得到右侧的最大序列和,可能不包含右侧的第一个元素....
*/
int maxRightSum = maxSumRec(a, center + 1, right);
/*
* 边界值...左侧最大序列和(包含最后一个元素)..
*/
int maxLeftBorderSum = 0,leftBorderSum = 0;
for(int i = center ; i>= left;i--){
leftBorderSum += a[i];
if(leftBorderSum > maxLeftBorderSum)
maxLeftBorderSum = leftBorderSum;
}
/**
* 右侧最大序列和(包含第一个起始元素)..
*/
int maxRightBorderSum = 0,rightBorderSum = 0;
for(int i = center + 1;i<right;i++){
rightBorderSum += a[i];
if(rightBorderSum > maxRightBorderSum)
maxRightBorderSum = rightBorderSum;
}
//...比较 maxLeftSum,maxRightSum,maxLeftBorderSum + maxRightBorderSum 三者的值,取最大的即为数组的最大序列和....
return max(maxLeftSum,maxRightSum,maxLeftBorderSum + maxRightBorderSum);
}
4.最大子序列...
①.最大子序列都不可能以负元素开始②.最大子序列都不会以负子序列作为前缀...
即:若a[i]到a[j]的子序列是负的.那么可以将i推进到j+1
public void test_4(){
int a[] = new int[10];
int thisSum = 0,maxSum = 0;
for (int i = 0; i < a.length; i++) {
thisSum += a[i];
if(thisSum > maxSum)
maxSum = thisSum;
else if(thisSum < 0)
thisSum = 0;
}
}