
【题目】:53. 最大子数组和
方法1. 前缀和
class Solution { public: int maxSubArray(vector<int>& nums) { int n = nums.size(); int res = INT_MIN; int cur = 0; vector<int> preSum(n + 1, 0); for(int i = 0; i < n; ++i) { preSum[i + 1] = nums[i] + preSum[i]; } for(int i = 0; i < n; ++i) { for(int j = i + 1; j <= n; ++j) { res = max(res, preSum[j] - preSum[i]); } } return res; } };
|
- 时间复杂度: O(n^2)
- 空间复杂度: O(n)
用preSum维护前缀和,然后循环preSum, preSum[j] - preSum[i]就是子数组i到j的和。但是这个方法会超时=。=
方法2. 动态规划
class Solution { public: int maxSubArray(vector<int>& nums) { int res = nums[0]; vector<int> dp(nums.size(), 0); dp[0] = nums[0]; for(int i = 1; i < nums.size(); ++i) { dp[i] = max(dp[i - 1], 0) + nums[i]; res = max(res, dp[i]); } return res; } };
|
方法3.
class Solution { public: int maxSubArray(vector<int>& nums) { int sum = 0; int res = INT_MIN; for(int i = 0; i < nums.size(); ++i) { if(sum >= 0) { sum += nums[i]; }else { sum = nums[i]; } res = max(res, sum); } return res; } };
|
如果sum是正数,说明sum + nums[i]对结果是促进作用;
如果sum是负数,说明sum + nums[i]对结果是抑制作用,直接丢弃前边累加的结果。