最大子列和问题
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int inputNum = Integer.parseInt(sc.nextLine());
String inputStr = sc.nextLine();
String[] strArray = inputStr.split(" ");
int array[] = new int[inputNum];
for (int i = 0; i < inputNum; i++) {
array[i] = Integer.parseInt(strArray[i]);
}
System.out.println(maxSubSeqSum(array));
}
//方法一,记录开始值和结束值之间的距离
public static String maxSubSeqSum(int[] array) {
int thisSum = 0; // 序列和累加变量
int maxSum = 0; // 最大和
boolean flag = true; // 判断是否需要修改最大子序列和的开始值。true:需要修改,false:不需要改
boolean allNeflag = true; // 判断输入项是否都为负数
int startNum = array[0]; // 最大子序列开始值
int endNum = array[0];// 最大子序列结束值
// 开始循环遍历序列,找出最大序列总、开始项和结束项
// j表示开始项到结束项之间的长度
for (int i = 0, j = 0; i < array.length; i++) {
thisSum += array[i];
// 判断当前累加和是否>最大累加值,需要特殊处理以0开始的序列
if (thisSum > maxSum || (maxSum == 0 && thisSum == 0)) {
allNeflag = false; // 只要有一项>=0,就置allNeflag为false
// 判断是否需要修改当前开始项
if (flag) {
// 开始项的值需要从当前项i向前移动j个单位长度
startNum = array[i - j];
flag = false; // 移动完后将flag置为false,将修改开始值的开关关掉
}
maxSum = thisSum; // 将最大值指向当前累加值。
endNum = array[i]; // 记录结束项的值
} else if (thisSum < 0) {
// 如果当前累加的值 < 0,将当前累加和置为0,并且将修改开始值的开关打开
thisSum = 0;
flag = true;
j = 0; // 将移动距离置为0
} else {
// thisSum>0,需要将移动距离+1
j++;
}
}
// 输出
if (allNeflag) {
// 如果都为负数,返回: 0 数组[开始项] 数组[结束项]
return 0 + " " + array[0] + " " + array[array.length - 1];
} else {
// 返回 最大子序列和 开始项值 结束项值
return maxSum + " " + startNum + " " + endNum;
}
}
//方法二:通过数组记录位置,从数组末尾向前遍历确定连续子列的开始项和结束项。
public static String maxSubSeqSum(int[] array) {
int thisSum = 0;
int maxSum = 0;
int j = 0;
int endNum = 0;
int[] startEndList = new int[array.length];
for (int i = 0; i < array.length; i++) {
thisSum += array[i];
if (thisSum > maxSum || (maxSum == 0 && thisSum == 0)) {
startEndList[j] = i;
endNum = j;
j++;
maxSum = thisSum;
} else if (thisSum < 0) {
thisSum = 0;
} else {
startEndList[j] = i;
j++;
}
}
if (j > 0) {
int startPos = startEndList[endNum];
for (int i = endNum; i >= 1; i--) {
if ((startEndList[i] - startEndList[i - 1]) == 1) {
startPos = startEndList[i - 1];
} else {
startPos = startEndList[i];
}
}
return maxSum + " " + array[startPos] + " " + array[startEndList[endNum]];
} else {
return 0 + " " + array[0] + " " + array[array.length - 1];
}
}
}