第一常规方法,时间复杂度O(n*n)
先从第一个元素开始向后累加,每次累加后与之前的和比较,保留最大值,
再从第二个元素开始向后累加,以此类推。
public static int maxSubSumQuadratic(int[] array) {
int maxSum = 0; //最大子序列求和
int maxStart = 0;
int maxEnd = 0;
//start表示要求和的子序列的开始索引,end表示结束索引
for(int start = 0; start < array.length; start++) {
int thisSum = 0; //当前子序列求和
for(int end = start; end < array.length; end++) {
//已求得的array[start]~array[end-1]子序列的和加上array[end]
//得到array[start]~array[end]子序列的和
thisSum += array[end];
//判断是否大于之前得到的最大子序列求和
if(thisSum > maxSum) {
maxSum = thisSum;
maxStart = start;
maxEnd = end;
}
}
}
System.out.println(maxStart);
System.out.println(maxEnd);
System.out.println(maxSum);
return maxSum;
}
第二:线性时间算法,最优方法,时间复杂度O(n)
和最大的子序列的第一个元素肯定是正数
因为元素有正有负,因此子序列的最大和一定大于0
该算法在每次元素累加和小于0时,从下一个元素重新开始累加
public static int maxSubSumLinear(int[] array) {
int maxSum = 0, thisSum = 0;
int maxStart = 0;
int maxEnd = 0;
for(int j = 0; j < array.length; j++) {
thisSum += array[j];
//如果累加和出现小于0的情况,
//则和最大的子序列肯定不可能包含前面的元素,
//这时将累加和置0,从下个元素重新开始累加
if (thisSum < 0) {
thisSum = 0;
maxStart = j+1;
}else if(thisSum > maxSum) {
maxSum = thisSum;
maxEnd = j;
}
}
System.out.println(maxStart);
System.out.println(maxEnd);
System.out.println(maxSum);
return maxSum;
}