53. Maximum Subarray
方法1: dynamic programming
思路:
因为是连续位置的数列和,只有两种情况,遍历到nums[i]的时候只能选择取或不取。取的话curSum = curSum + nums[i] ,或者以 i 为起点重新开始累计nums[i],这两种中的较大值就是以当前点为截止能取到的最大和,记录为cur并继续前进。每次移动更新全局最大变量result。
Complexity
Time complex: O(n)
Space complexity: O(1)
易错点:
- initial
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if (nums.size() == 0) return 0;
int n = nums.size();
int result = INT_MIN;
int curSum = 0;
for (int i = 0; i < n; i++){
curSum = max(curSum + nums[i], nums[i]);
result = max(result, curSum);
}
return result;
}
};
方法2: divide and conquer
思路:
用分治的做法需要找出1. 左半边的最大和, 2. 右半边的最大和,3. 跨越左边和右边的最大和= 左半边以mid - 1为止的连续和 + 右半边以mid + 1 为止的连续和 + nums[mid]。注意3不能从1、2 直接相加,因为1,2,的最大和有可能不与mid接壤。必须在算好1、2后再滚动一次左连续统计最大,再滚动统计右连续最大。
易错点:
不要漏掉中间仅一个数即为最大和的情况
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if (nums.size() == 0) return 0;
return subHelper(nums, 0, (int)nums.size() - 1);
}
int subHelper(vector<int> & nums, int left, int right){
if (left >= right) return nums[left];
int mid = left + (right - left) / 2;
int lmax = subHelper(nums, left, mid - 1) ;
int rmax = subHelper(nums, mid + 1, right);
int t = nums[mid];
int mmax = t;
for (int i = mid - 1; i >= left; i--){
t += nums[i];
mmax = max(mmax, t);
}
t = mmax;
for (int i = mid + 1; i <= right; i++){
t += nums[i];
mmax = max(mmax, t);
}
return max(mmax, max(lmax, rmax));
}
};