题目描述
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.click to show more practice.More practice:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
- 思路
求最大连续子序列的值。第一种方法是从头开始遍历,每当当前累加值小于0时则变为当前值(因为下一个数无论正负都会比直接等于当前值更小),否则继续累加。记录变化中的最大值。第二种方法是将数组递归分成两部分(类似归并排序),每部分求连续最大值,最后与存在于中间的连续序列的最大值比较得出最终的最大连续子序列值。(一定要亲自写写)
//第一种方法
public class Solution {
public int maxSubArray(int[] A) {
if(A == null)
return 0;
int sum = A[0];
int maxV = A[0];
for(int i=1; i<A.length; i++){
if(sum < 0)
sum = A[i];
else
sum += A[i];
maxV = Math.max(maxV, sum);
}
return maxV;
}
}
//第二种方法
public class Solution {
public int maxSubArray(int[] A) {
if(A == null)
return 0;
return margeMax(A, 0, A.length-1);
}
public int margeMax(int[] arr, int left, int right){
if(left >= right)
return arr[left];
int mid = left + (right - left) / 2;
int leftMax = margeMax(arr, left, mid);
int rightMax = margeMax(arr, mid+1, right);
//从中间开始求最大连续子区间值
//左区间
int lMax = arr[mid];
int temp = 0;
for(int i=mid; i>=left; i--){ //倒序,从中间发散求连续区间最大值
temp += arr[i];
lMax = Math.max(lMax, temp);
}
//右区间
int rMax = arr[mid+1];
temp = 0;
for(int i=mid+1; i<=right; i++){
temp += arr[i];
rMax = Math.max(rMax, temp);
}
return Math.max(lMax+rMax, Math.max(leftMax, rightMax)); //结果相加后与另外两区间取最大值
}
}