您的位置:首页 > 其它

53. Maximum Subarray

2016-01-12 22:23 274 查看
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

For example, given the array [−2,1,−3,4,−1,2,1,−5,4],

the contiguous subarray [4,−1,2,1] has the largest sum = 6.

动态规划。

对于数组nums,以nums[i]结尾的子数组最大值为

max[i] = nums[i]+Math.max(max[i-1],0)

由于当前max[i]仅和max[i-1]有关,可以简化成一个变量

public int maxSubArray(int[] nums) {
int l = nums.length;
if (l == 0) return 0;
if (l == 1) return nums[0];
int last = nums[0];   //以nums[i]结尾的子数组最大值
int max = last;     //最大子数组最大值
for (int i = 1; i < l; i++) {
if (last <= 0 ) {
last = nums[i];
}
else {
last = last +nums[i];
}
max = Math.max(max, last);
}
return max;
}


提示说:If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

总体思想:left middle right 之间的最大子数组为left~middle,middle+1~right,和middle向两侧扩展的子数组三个的最大值。

public int maxSubArray(int[] nums) {
int l = nums.length;
if (l == 0) return 0;
if (l == 1) return nums[0];
return helper(nums,0,l-1);
}
private int helper(int[] nums,int left,int right){
if(left == right) return nums[left];
int middle = (right - left)/2+left;
int leftpart = helper(nums,left,middle);       //左半边最大值
int rightpart = helper(nums,middle+1,right);   //右半边最大值
int leftmax = nums[middle],rightmax = nums[middle+1];  //从middle向两侧扩展的最大值
int tmp = 0;
for(int i = middle;i >= left;i--){
tmp += nums[i];
leftmax = Math.max(tmp,leftmax);
}
tmp = 0;
for(int i = middle+1;i <= right;i++){
tmp += nums[i];
rightmax = Math.max(tmp,rightmax);
}
return Math.max(Math.max(leftpart,rightpart),rightmax+leftmax);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: