《编程之美》- 2.14 - 求数组的子数组之和的最大值

来源:互联网 发布:声音好听的网络男歌手 编辑:程序博客网 时间:2024/06/08 09:45

题目

一个有N个整数元素的一维数组,{A[0]...A[n-1]},求该数组所有子数组中的最大和。
题意明确:
  1. 题目中说的子数组是连续的;
  2. 题目只需要求和,并不需要返回子数组的具体位置;
  3. 数组的元素是整数,所以数组可能包含有正整数,零和负整数;
例:
数组[ 1,-2,3,5,-3,2 ]返回8;

分析

《编程之美》P183-188中详细讲述了,该题目从最初暴力O(n^3)的解法,优化到最后O(N)的步骤;

代码

/*2.14 求数组的子数组之和的最大值*/#include <iostream>#include <cstdlib>#include <vector>#include <algorithm>using namespace std;/*方法一:罗列所有的子数组,求每个子数组的和,时间复杂度O(n^3)*/int maxSubSum(const vector<int> &nums){if (nums.empty()){return 0;}//ifint len = nums.size();int maxSum = INT_MIN, tmpSum = 0;for (int i = 0; i < len; ++i){for (int j = i; j < len; ++j){/*清0临时子数组的和*/tmpSum = 0;/*求i到j的子数组之和*/for (int k = i; k <= j; ++k){tmpSum += nums[k];}//forif (tmpSum > maxSum){maxSum = tmpSum;}//if}//for}//forreturn maxSum;}/*方法二:注意到sum[i...j] = sum[i-1 ... j] + nums[j] , 复杂度降低到O(n^2)*/int maxSubSum2(const vector<int> &nums){if (nums.empty()){return 0;}//ifint len = nums.size();int maxSum = INT_MIN, tmpSum = 0;for (int i = 0; i < len; ++i){tmpSum = 0;for (int j = i; j < len; ++j){tmpSum += nums[j];/*从i到j的子数组之和为tmpSum*/if (tmpSum > maxSum)maxSum = tmpSum;}//for}//forreturn maxSum;}/*方法三:分治法的思想,分为规模减半的子问题,通过递归解决;复杂度O(nlogn)*//*方法四:动态规划max{A[0], A[0]+start[1], ALL[1]},时间复杂度O(N),空间复杂度O(N)*/int maxSubSum4(const vector<int> &A){if (A.empty()){return 0;}//ifint len = A.size();/*Start数组中存放的是,以下标i对应元素为起始点的最大子数组之和*/vector<int> Start(len, 0);/*All数组中存放的是,从下标[i...len-1]实际最大子数组之和*/vector<int> All(len, 0);/*从数组末尾向前遍历,知道数组首部*/Start[len - 1] = A[len - 1];All[len - 1] = A[len - 1];for (int i = len - 2; i >= 0; --i){Start[i] = max(A[i], A[i] + Start[i + 1]);All [i] = max(Start[i], All[i + 1]);}//forreturn All[0];}/*方法五:四的改进,空间复杂度减低到O(1)*/int maxSubSum5(const vector<int> &A){if (A.empty()){return 0;}//ifint len = A.size();int nStart = A[len - 1], nAll = A[len - 1];for (int i = len - 2; i >= 0; --i){nStart = max(A[i], nStart + A[i]);nAll = max(nStart, nAll);}//forreturn nAll;}/*方法六:线性时间复杂度*/int maxSubSum6(const vector<int> &A){if (A.empty()){return 0;}//if/*求数组A的长度*/int n = A.size();int maxSum = A[n - 1], tmpSum = A[n - 1];for (int i = n - 2; i >= 0; --i){if (tmpSum < 0){tmpSum = 0;}//iftmpSum += A[i];if (tmpSum > maxSum)maxSum = tmpSum;}//forreturn maxSum;}int main(){vector<int> A = { 1,-2,3,5,-3,2 };cout << maxSubSum(A) << endl;cout << maxSubSum2(A) << endl;cout << maxSubSum4(A) << endl;cout << maxSubSum5(A) << endl;cout << maxSubSum6(A) << endl;system("pause");return 0;}



0 0
原创粉丝点击