问题
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
解答
动态规划方法,时间复杂度为 O(n)
class Solution {
public int maxSubArray(int[] nums) {
int sum = nums[0];
int []t = new int [nums.length];
t[0] = nums[0];
int start=0,temp=0,end=0;
for(int i=1;i<nums.length;i++){
if(t[i-1] > 0){
t[i] = t[i-1] + nums[i];
}else{
t[i] = nums[i];
temp = i;
}
if(sum < t[i]){
sum = t[i];
start = temp;
end = i;
}
}
return sum;
}
}
分治法 [未验证]
时间复杂度为 O(NlogN)
private static int maxSubArray(int [] a , int left , int right){
if( left == right ){//边界①
if( a[left] > 0 )
return a[left];
else
return 0;
}
int center = (left + right) / 2;
int maxLeftSum = maxSubArray( a, left, center);
int maxRightSum = maxSubArray( a, center + 1, right);
int maxLeftBorderSum = 0, leftBorderSum = 0;
for( int i = center; i >= left; i--){
leftBorder += a[i];
if( maxLeftBorderSum < leftBorderSum)
maxLeftBorderSum = leftBorderSum;
}
int maxRightBorderSum = 0, rightBorderSum = 0;
for( int i = center + 1; i <= right; i ++){
rightBorderSum += a[i];
if( maxRightBorderSum > rightBorderSum)
maxRightBorderSum = rightBorderSum;
}
return max( maxRightBorderSum + maxLeftBorderSum ,
maxLeftSum , maxRightSum);
}