通过两层for循环遍历每一种可能的组合,再通过比较得到最大的值。方法实现较为简单,但时间复杂度较高,需要O(n*n),代码如下:
class Solution { public: int maxSubArray(vector<int> & nums) { int number = nums.size(); int currentSum = 0; int max = nums[0]; //n个数则总共执行n次循环 for (int i = 0; i < number; ++i) { currentSum = 0; for (int j = i; j < number; ++j) { currentSum += nums[j]; if (currentSum > max) max = currentSum; } } return max; } };这个算法的时间复杂度较暴力求解有了一定的提升。设数组的长度为n, 时间复杂度为T(n),则时间复杂度为T(n) = 2 * T(n / 2) + 0(n),可计算得时间复杂度为0(nlgn)。
代码如下:
class Solution { public: int maxSubArray(vector<int> & nums) { int currentSum = 0; int max = nums[0]; for (int i = 0; i < nums.size(); ++i) { currentSum += nums[i]; if (currentSum > max) max = currentSum; if (currentSum < 0) currentSum = 0; } return max; } }; 从第一个数开始累加,如果是正的则一直保持,负的则舍弃重新累加。max一直保留目前的最大值。该算法的思想是已知原数组后面部分的最大子数组nAll以及该部分最前一个元素开始的最大子数组nStart。然后再往前添加一个元素,则此时新数组的最大子数组要么是包含新元素,要么是原来的最大子数组。如果包含新元素,则是新元素本身或者是新元素加上原来的nStart的和。时间复杂度为O(n)。 代码如下:
class Solution { public: int maxSubArray(vector<int> & nums) { int nStart = nums[nums.size() - 1]; int nAll = nums[nums.size() - 1]; for (int i = nums.size() - 2; i >= 0; --i) { nStart = max(nums[i], nums[i] + nStart); nAll = max(nAll, nStart); } return nAll; } int max(int x, int y) { return (x > y) ? x : y; } };如果有一张近期股票的走势图,要问你哪天买入哪天卖出能得到最大收益。此时可以转为最大子数组问题。数组元素为前后两天的股票差值。