一、题目
二、代码
前面已经使用动态规划解决,现在使用分治算法。
- 子区间 [left, mid]的最大和。
- 子区间 [mid + 1, right]的最大和。
- 包含子区间[mid , mid + 1]的子区间,即 nums[mid] 与nums[mid + 1]一定会被选取,因为
nums[mid]
与nums[mid + 1]
一定会被选取,所以从中间向两边扩展,选出最大值和。 - 比较以上三者,找出最大值即为答案。
public class Solution {
public int maxSubArray(int[] nums) {
int len = nums.length;
return maxSubArray_(nums, 0, len - 1);
}
public int maxSubArray_(int nums[], int left, int right){
if(left == right){
return nums[left];
}
int mid = (left + right) / 2;
//左侧子区间 [left, mid]的最大和
int leftMaxSum = maxSubArray_(nums, left, mid);
//右侧子区间 [mid + 1, right]的最大和
int rightMaxSum = maxSubArray_(nums, mid + 1, right);
//包含[mid , mid + 1]的子区间的最大和
int leftCrossMax = Integer.MIN_VALUE;
int leftCrossSum = 0;
for(int i = mid; i >= 0; i--){
leftCrossSum += nums[i];
if(leftCrossSum > leftCrossMax){
leftCrossMax = leftCrossSum;
}
}
int rightCrossMax = Integer.MIN_VALUE;
int rightCrossSum = 0;
for(int i = mid + 1; i <= right; i++){
rightCrossSum += nums[i];
if(rightCrossSum > rightCrossMax){
rightCrossMax = rightCrossSum;
}
}
int CrossMax = leftCrossMax + rightCrossMax;
return Math.max(CrossMax, Math.max(leftMaxSum, rightMaxSum));
}
}