【剑指offer】30:连续子数组的最大和
题目描述:
输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为 O(n).
例如:
数组:[1,-2,3,10,-4,7,2,-5]
最大的子数组为{3,10,一4,7,2},因此输出为该子数组的和 18。
解题思路:
本题可以看做是一个多阶段决策找最优解的问题,因此可以用典型的动态规划思想来求解。用 [ i ] 表示以第 i 个元素结尾的子数组的最大和,那么有以下递推公式:temp = temp + array[i] > array[i] ? temp + array[i] : array[i];
这个公式的含义是:当以第i个数字结尾的子数组中所有数字的和小于0时,把这个负数与第i个数累加,则得到的和比第i+1个数字本身还要小,所以这种情况下array[ i ]就是第i个数字本身。反之,如果以第i个数字结尾的子数组中所有数字的和大于0,则与第i+1个数字累加就得到以第i个数字结尾的子数组中所有数字的和。
例如:
[1,-2,3,10,-4,7,2,-5]
步骤 | 操作 | 累加子数组和 | 最大子数组和 |
1 | +1 | 1 | 1 |
2 | +(-2) | -1 | 1 |
3 | +3(舍去之前的负一) | 3 | 3 |
4 | +10 | 13 | 13 |
5 | +(-4) | 9 | 13 |
6 | +7 | 16 | 16 |
7 | +2 | 18 | 18 |
8 | +(-5) | 13 | 18 |
9 |
代码实现
(C实现):
int FindGreatestSumOfSubArray(int* array, int arrayLen ) { // write code here if (arrayLen == 0) return 0; if (arrayLen == 1) return array[0]; int temp = array[0], result = temp; for (int i = 1; i < arrayLen; i++) { temp = temp + array[i] > array[i] ? temp + array[i] : array[i]; if (temp > result) { result = temp; } } return result; }