略
输入一个整型数组,数组中有正数也有负数,这个数组中一个或者连续多个整数组成的子数组,求其子数组的最大(最小)值.要求时间复杂度为O(n).例如数组{1,-2,3,10,-4,7,2,-5},它的最大子段为{3,10,-4,7,2},和为18.
分析
很多人直观的想法是枚举该数组的所有子数组的和,一个长度为n的数组,一共有n(n-1)/2个子数组,计算所有和时间复杂度至少为O(n²),不符合题目,所以要用另外一个方法来解.
我们可以从数组开头来累加每个元素,例如{1}最大为1,{1,-2}最大为1,{1,-2,3}最大为3,此时因为加上{1,-2}这两条数据后子段不加反减,所以需要排除掉{1,-2},从{3}开始累加,{3,10}最大13,{3,10,-4}最大为13,{3,10,-4,7}最大为16,{3,10,-4,7,2}最大为18,{3,10,-4,7,2,-5}最大为18,此时数组完全都被遍历,所以排除掉{-5}.此时得到最大子段和为18.
步骤 | 操作 | 叠加的子段和 | 最大子段和 |
---|---|---|---|
1 | 加1 | 1 | 1 |
2 | 加-2 | -1 | 1 |
3 | 放弃前面的和-1加3 | 3 | 3 |
4 | 加10 | 13 | 13 |
5 | 加-4 | 9 | 13 |
6 | 加7 | 16 | 16 |
7 | 加2 | 18 | 18 |
8 | 加-5 | 13 | 18 |
代码实现
1 | public static int findGreatestSumOfArray(int[] arr) { |
总结
跳出组合的圈子,对于大数据不要尝试使用枚举,注意时间复杂度.