练习题目
给定数组 [ a0, a1, a2, …, an ] ,找出其最大连续子序列和,要求时间复杂度为 O(n),数组包含负数。
例如:输入 [ -2,11,-4,13,-5,-2] ,输出 20(即 11 到 13)。
解答
关于这个问题有很多种解法,这里介绍一种时间复杂度仅为 O(n) 的解法,即只需要一次循环即可。
代码:public class Main {
public static void main(String[] args) {
int[] array = new int[]{2, -3, 23, 3, -12, -1, 2, 34, -30, 12, 2};
int maxSum = 0;
int thisSum = 0;
for (int i = 0; i < array.length; i++) {
thisSum += array[i];
if(thisSum > maxSum) {
maxSum = thisSum;
} else if (thisSum < 0) {
thisSum = 0;
}
}
System.out.println(maxSum);
}
}
运行结果:49
最大子序列和即 [23, 3, -12, -1, 2, 34]。
分析
上面代码中使用到了两个变量 thisSum 和 maxSum 存储最大值,其中 maxSum 为最终的最大连续子序列和,而 thisSum 表示遍历到当前位置时的和。
由于最大子序列和不可能以一个负数起始(我们总能够找到其后一个非负数作为起始位置,使得其和大于它)。所以当 thisSum 小于 0 时,我们需要将其设置为 0,因为前面部分的和为负数时是没有意义的。