Given an array of integers, find two non-overlapping subarrays which have the largest sum.
The number in each subarray should be contiguous. Return the largest sum.
Example:
For given [1, 3, -1, 2, -1, 2], the two subarrays are [1, 3] and [2, -1, 2] or [1, 3, -1, 2] and [2], they both have the largest sum 7.
解法:动归。对于每个element i, 分别记录 [0, i ] 的left maxsum和(i, n)的right maxsum,最后扫描一遍记录,找到left + right最大的sum.
注意:因为subarray最少也要包含一个element,且subarray不应该overlap, 把left[i] 定位为结尾到 i 中的 maxsum(这个subarray可能包含i,也可能不包含i), right[i] 代表以i+1开头 往后中的maxsum.
算法公式:
对于left[i]来说,如果包含 i,最大值是Math.max( left[i-1] + nums[i],nums[i] ); 如果不包含 i, 最大值是left[i-1];
对于right[i]来说,如果包含i+1, 最大值是Math.max(right[i+1] + nums[i+1], nums[i+1]), 如果不含i+1, 最大值是right[i+1];
public int maxTwoSubArrays(ArrayList<Integer> nums) {
int res = Integer.MIN_VALUE;
if (nums.size() == 0) return res;
// calculate from left and record max
int[] left = new int[nums.size()];
// localmax is subarray ends in i;
int localmax = nums.get(0);
// globalmax is subarray within 0~i;
int globalmax = Integer.MIN_VALUE;
left[0] = nums.get(0);
for (int i = 1; i < nums.size(); i++) {
localmax = Math.max(localmax + nums.get(i), nums.get(i));
globalmax = Math.max(localmax, globalmax);
left[i] = globalmax;
}
// right local max is subarray ends in i+1
localmax = 0;
globalmax = Integer.MIN_VALUE;
for (int i = nums.size()-2; i >= 0; i--) {
localmax = Math.max(localmax + nums.get(i+1), nums.get(i+1));
globalmax = Math.max(localmax, globalmax);
res = Math.max(res, globalmax+left[i]);
}
return res;
}