注:爲方便起見,如果所有整數均爲負數,則最大子序列和爲0。
算法一,窮舉法,找出所有子數組,然後求出子數組的和,在所有子數組的和中取最大值
/*O(n^3)窮舉法
* 缺點:重複累加,與maxSum比較,每次i->j中間累加完了才與maxSum比較
* */
public static int MaxSubSequence1(int[] array){
int length=array.length;
int maxSum=0;
int thisSum=0;
for(int i=0;i<length;i++){
for(int j=i;j<length;j++){
thisSum=0;
for(int k=i;k<j;k++){//把i->j之間累加起來
thisSum+=array[k];
if(thisSum>maxSum){
maxSum=thisSum;
}
}
}
}
return maxSum;
}
算法二,第一種方法每次i->j之間都要迭代一遍,重複計算了很多,可以利用已經計算的子數組的和
/*O(n^2)窮舉法
* i->j之間每累加一次就和maxsum比較
* */
public static int MaxSubSequence2(int[] array){
int length=array.length;
int maxSum=0;
int thisSum=0;
for(int i=0;i<length;i++){
thisSum=0;
for(int j=i;j<length;j++){
thisSum+=array[j];
if(thisSum>maxSum){
maxSum=thisSum;
}
}
}
return maxSum;
}
算法三,動態規劃,初始化一個最大值數組MaxSum[n],MaxSum[i]就表示A[0...i]以A[i]結尾的子數組最大和,那麼MaxSum[i]就等於A[0...i-1]的最大和加上A[i]在和A[i]比較求最大值, MaxSum[i] = Max{ MaxSum[i-1] + A[i], A[i]}
//動態規劃,狀態方程 MaxSum[i] = Max{ MaxSum[i-1] + A[i], A[i]};MaxSum[i]表示已a[i]結尾的最大和
public static int MaxSubSequence3(int[] array){
int length=array.length;
int[] MaxSum=new int[length];
MaxSum[0]=array[0];
for(int i=1;i<length;i++){
MaxSum[i]=Math.max(MaxSum[i-1]+array[i], array[i]);
}
//找到MaxSum中的最大值
int maxSum=Integer.MIN_VALUE;
for(int i=0;i<MaxSum.length;i++){
if(MaxSum[i]>maxSum){
maxSum=MaxSum[i];
}
}
return maxSum;
}
算法三的改進O(n)
/*
* 方法三的簡化,當前面的累加和thisSum小於0是就置0,丟棄,大於maxSum時,把值賦給maxSum
* */
public static int MaxSubSequence4(int[] array){
int length=array.length;
int maxSum=0;
int thisSum=0;
for(int i=0;i<length;i++){
thisSum+=array[i];
if(thisSum>maxSum){
maxSum=thisSum;
}
else if(thisSum<0){
thisSum=0;
}
}
return maxSum;
}