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.
Notice
The subarray should contain at least one number
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
.
算法:分别算出left[]从左开始的最小subarray和right[]从右开始的最大subarray,然后开始求left[i] + right[i+1]的最大值。因为要求不重叠,所以你可以想象你在不断挪动一个分割线,最后的结果就是找到那个分割线i,从最左开始到分割线左边和从最右开始到分割线右边这两个分开的subarray加起来是最大的。
实现:
public class Solution { /* * @param nums: A list of integers * @return: An integer denotes the sum of max two non-overlapping subarrays */ public int maxTwoSubArrays(List<Integer> nums) { // write your code here if (nums == null || nums.size() == 0) { return 0; } int[] sums = new int[nums.size() + 1]; for (int i = 0; i < nums.size(); i++) { sums[i + 1] = sums[i] + nums.get(i); } int preMin = 0; int maxSum = Integer.MIN_VALUE; int[] left = new int[nums.size() + 1]; for (int i = 1; i < sums.length; i++) { int crtSum = sums[i] - preMin; maxSum = Math.max(maxSum, crtSum); left[i] = maxSum; preMin = Math.min(preMin, sums[i]); } for (int i = 0; i < nums.size(); i++) { sums[i + 1] = sums[i] + nums.get(nums.size() - 1 - i); } preMin = 0; maxSum = Integer.MIN_VALUE; int[] right = new int[nums.size() + 1]; for (int i = 1; i < sums.length; i++) { int crtSum = sums[i] - preMin; maxSum = Math.max(maxSum, crtSum); right[sums.length - i] = maxSum; preMin = Math.min(preMin, sums[i]); } int maxTotalSum = Integer.MIN_VALUE; for (int i = 1; i + 1 < right.length; i++) { maxTotalSum = Math.max(maxTotalSum, left[i] + right[i + 1]); } return maxTotalSum; } }