题目:
给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
分析思路:
首先肯定是暴力求解法,找到一个可行解。然后进一步对暴力求解法进行优化。
暴力求解法通过两个循环遍历,找到所有子序,比较所有子序和得到最大子序和。暴力解法存在很多冗余的计算。当sum(a_i, a_(i+1), a_(i+2)) <=0 时,那么以此3项作为开头的所有子序都可以剔除,不再考虑。利用上面这一特性,我们可以对暴力解法进行优化,得到时间复杂度为O(n)的算法。
class Solution { public: int maxSubArray(vector<int>& nums) { int maxV = nums[0]; int index = 0; while(index < nums.size()) { int sum = 0; for(index; index < nums.size(); ++index) { sum = sum + nums[index]; maxV = max(maxV, sum); if(sum <= 0) { index += 1; break; } } } return maxV; } };
时间复杂度:O(n)
空间复杂度:O(1)
分治法。记最大子序和为maxResult,函数为int getMaxSub( *, * ) {}。
向量A= [a1, a2, a3, ...., ai, ai+1, a+2, ......, aj-1, aj],
maxResult = max( maxresult(a1, ......, ai), getMaxSub(*, i+1) ),其中sum(a1, ......, ai) <= 0.
时间复杂度:O(n)
空间复杂度:O(n) ???
class Solution { public: int maxSubArray(vector<int>& nums) { if(nums.size() == 0) return -1; return getMaxSub(nums, 0); } int getMaxSub(const vector<int>& vecInt, int index) { int maxR = vecInt[index], sum = 0; for(index; index < vecInt.size(); ++index) { sum = sum + vecInt[index]; if(sum <= 0 && index < (vecInt.size() - 1)) { // 确保下一级序列非空 maxR = max(maxR, getMaxSub(vecInt, index+1)); return maxR; } else { maxR = max(maxR, sum); } } return maxR; } };
执行用时 :12 ms, 在所有 C++ 提交中击败了64.15%的用户
内存消耗 :9.4 MB, 在所有 C++ 提交中击败了76.19%的用户