Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array
the contiguous subarray
[-2,1,-3,4,-1,2,1,-5,4]
,
the contiguous subarray
[4,-1,2,1]
has the largest sum =
6
.
本题的题意就是让我们去寻找和最大的子序列,这是一道可以用分治算法解决的题目。
首先,我们可以把传入的数组如何得出最大的和进行讨论,发现最终最大的和出现在下面三种情况中:
1.左半部分的部分或全部数相加产生最大的和。(这些数都是最开始给定的数组的子序列)
2.右半部分的部分或全部数相加产生最大的和。(这些数都是最开始给定的数组的子序列)
3.中间的数和两边的0个或多个数相加产生最大的和。(这些数都是最开始给定的数组的子序列)
这三种情况的最大的和里的最大值就是答案。
这样的话,我们就可以借鉴归并排序的思路来完成这道题,将数组不断分成更小的数组,然后先求出小数组的连续子序列的最大值,最后可以从下到上再求出最大的数组的连续子序列的最大值。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if (nums.empty()) return 0;
return helper(nums, 0, nums.size() - 1);
}
int helper(vector<int>& nums, int left, int right) {
if(left >= right) return nums[left];
int mmax;
int maxleft, maxright, sum = 0;
int mid = left+(right-left)/2;
mmax = nums[mid];
sum = nums[mid];
maxleft = helper(nums, left, mid-1);
maxright = helper(nums, mid+1, right);
for(int i = mid-1; i >= left; i--) {
sum += nums[i];
mmax = max(sum, mmax);
}
sum = mmax;
for(int i = mid+1; i <= right; i++) {
sum += nums[i];
mmax = max(sum, mmax);
}
return max(mmax, max(maxleft, maxright));
}
};
首先我将mid定义为传入的left+(right-left)/2。
然后maxx和sum都被赋值为nums[mid],其中maxx用于表示中间的数和两边的0个或多个数相加产生的最大值。
中间的数与左半部分的数(从nums[mid-1]开始)相加得出的最大值再和右半部分的数(从nums[mid+1]开始)相加最终得出maxx的值。
helper函数的返回值就是三种情况里面最大的值。
maxleft是第一种情况的最大值,maxright是第二种情况的最大值。
最开始的maxSubArray函数只需要调用helper函数并且将数组以及数组传入即可。之后helper函数就会递归调用自己。