题目:输入一个整型数组,数组里有正数也由负数。数组中一个或者连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为 O(n)。
例如输入的数组为{1,-2,3,10,-4,7,2,-5},其最大的子数组为{3,10,-4,7,2},因此所有子数组的和的最大值为 18。
应用动态规划法:
我们需要保存两个值,一个存放遍历到当前位置的和kCurSum,另一个存放遍历到当前位置时的最大和kGreatestSum。假设现在我们遍历到第K个位置的元素:
1、如果当前的和kCurSum小于等于0,那么我们置当前和为遍历到的当前元素arr[k];
2、如果,kCurSum大于 0, 那么我们将 kCurSum 置为 kCurSum 与 arr[k] 的和;
3、将变化后的 kCurSum 与当前最大和 kGreatestSum 比较;
4、如果前者kCurSum 大于 后者kGreatestSum,将 kGreatestSum 置为 kCurSum;
4、否则,继续遍历;
完整代码如下:
1 #include <iostream> 2 #include <stdexcept> 3 4 bool isAllElemsNegative(int *arr, int len); 5 int findMaxNum(int *arr, int len); 6 7 int findGreatestSumOfSubArray(int *arr, int len) 8 { 9 if(arr == NULL || len <= 0) 10 throw std::out_of_range("Invalid Input"); 11 12 int nMaxSum = 0; 13 int curSum = 0; 14 15 if(isAllElemsNegative(arr, len)) 16 { 17 return findMaxNum(arr, len); 18 } 19 20 for(int i = 0; i < len; ++i) // 数组存在正数 21 { 22 if(curSum <= 0) 23 curSum = arr[i]; 24 else 25 curSum += arr[i]; 26 27 if(curSum > nMaxSum) 28 nMaxSum = curSum; 29 } 30 return nMaxSum; 31 } 32 33 bool isAllElemsNegative(int *arr, int len) 34 { 35 bool isNegative = true; 36 37 for(int i = 0; i < len; ++i) 38 { 39 if(arr[i] >= 0) 40 { 41 isNegative = false; 42 break; 43 } 44 } 45 return isNegative; 46 } 47 48 int findMaxNum(int *arr, int len) 49 { 50 int num = arr[0]; 51 for(int i = 1; i < len; ++i) 52 { 53 if(arr[i] > num) 54 num = arr[i]; 55 } 56 return num; 57 } 58 59 int main(int argc, char *argv[]) 60 { 61 // int arr[8] = {1, -2, 3, 10, -4, 7, 2, -5}; 62 int arr[8] = {-3, -5, -2, -9, -12, -1, -90, -5}; 63 int max = findGreatestSumOfSubArray(arr, 8); 64 std::cout << "The max Sum is: " << max << std::endl; 65 66 return 0; 67 }
本文完。