53. Maximum Subarray
Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.
Example:
Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
Follow up:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
解法一
遍历数组,每次尽可能延长当前的区间(无论下一个数字的正负),直到遇到一个数字比当前区间所有数加起来的和还大,此时开始遍历新的区间。每次记录下最大的和即为最大子区间的和。
class Solution {
public:
//O(n)
int maxSubArray(vector<int>& nums){
int res = INT_MIN, sum = 0;
for (auto num: nums){
sum = max(sum + num, num); //lengthen or start a new interval
res = max(sum, res);
}
return res;
}
}
解法二
分治法,最大子区间要么在左半部分,要么在右半部分,要么在中间。
其中中间的区间为从中间为起点,到左、右两边分别sum最大的区间。
class Solution {
public:
//--divide and conquer--
int maxSubArray(vector<int>& nums) {
return div_con(nums, 0, nums.size() - 1);
}
int div_con(vector<int>& nums, int s, int n){
if (n < s) return 0;
if (n == s) return nums[s];
int mid = (s + n) / 2;
//left , right
int left_max = div_con(nums, s, mid);
int right_max = div_con(nums, mid + 1, n);
//middle = part of left and part of right
int mid_left_max = INT_MIN, mid_left = 0;
for (int i = mid; i >= 0; i--){
mid_left += nums[i];
mid_left_max = max(mid_left_max, mid_left);
}
int mid_right_max = INT_MIN, mid_right = 0;
for (int i = mid + 1; i <= n; i++){
mid_right += nums[i];
mid_right_max = max(mid_right_max, mid_right);
}
int middle_max = mid_left_max + mid_right_max;
if (left_max > right_max) return max(left_max, middle_max);
return max(right_max, middle_max);
}
};