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
.解体思路:
1. 数组A[0..j]的最大和来自于子数组A[0..j-1]或者来自于A[i..j]
2. 对于A[i..j]的最大数,是 A[i..j-1]+A[j] or A[j]
3. 使用divide-conquer 解法:A[0..n]的最大值来自于3个地方:左边子数组A[0..j], 右边子数组 A[j+1..n]的最大值,或者跨越这两个数组之间的最大值,也就是一定包含A[j],A[j+1]的最大值。
public int maxSubArray(int[] A) { if(A.length == 0) return 0; int maxSum = A[0]; int sum = A[0]; for(int i = 1; i < A.length; i++){ sum = A[i] > sum + A[i] ? A[i] : sum + A[i]; maxSum = Math.max(maxSum, sum); } return maxSum; }
divide-conquer的解法
public int maxSubArray(int[] A) { if (A.length == 0) return 0; return maxSubarray(A, 0, A.length - 1); } public int maxSubarray(int[] A, int start, int end) { int mid = (start + end) / 2; int leftMax = Integer.MIN_VALUE; int rightMax = Integer.MIN_VALUE; int crossMax = Integer.MIN_VALUE; int maxSum = 0; if(start == end) return A[start]; if (mid >= start) { leftMax = maxSubarray(A, start, mid); } if (mid < end) { rightMax = maxSubarray(A, mid + 1, end); } if (mid >= start && mid < end) { int sum = A[mid]; crossMax = A[mid]; for (int j = mid - 1; j >= start; j--) { sum += A[j]; crossMax = Math.max(sum, crossMax); } crossMax+= A[mid+1]; sum = crossMax; for (int i = mid + 2; i <= end; i++) { sum += A[i]; crossMax = Math.max(sum, crossMax); } } maxSum = Math.max(leftMax,rightMax); maxSum = Math.max(maxSum, crossMax); return maxSum; }
No comments:
Post a Comment