问题:
给定数组,求两个固定长度M和L的子数组(不相交)之和最大为多少
Example 1: Input: A = [0,6,5,2,2,5,1,9,4], L = 1, M = 2 Output: 20 Explanation: One choice of subarrays is [9] with length 1, and [6,5] with length 2. Example 2: Input: A = [3,8,1,3,2,1,8,9,0], L = 3, M = 2 Output: 29 Explanation: One choice of subarrays is [3,8,1] with length 3, and [8,9] with length 2. Example 3: Input: A = [2,1,5,6,0,9,5,0,3,8], L = 4, M = 3 Output: 31 Explanation: One choice of subarrays is [5,6,0,9] with length 4, and [3,8] with length 3. Note: L >= 1 M >= 1 L + M <= A.length <= 1000 0 <= A[i] <= 1000
解法:
L和M的关系可能为以下两种:
[..L..M..]
[..M..L..]
我们可以固定右边的子数组M(或L)
求左边的子数组最大和Lmax(或Mmax)
对每一组Lmax+M,求最大和,再向右移动M
同样,对每一组Mmax+L,求最大和,再向右移动L
再对这两种情况求最大值。res=max(res, max(Lmax+M, Mmax+L))
另,子数组求和,我们可利用前缀数组求和法。
sum(i~j)=presum(j)-presum(i-1)
代码参考:
1 class Solution { 2 public: 3 int maxSumTwoNoOverlap(vector<int>& A, int L, int M) { 4 int Lmax=0;//L->M 5 int Mmax=0;//M->L 6 //sum[i-j]=presum[j]-presum[i-1] 7 int res=0; 8 for(int i=1; i<A.size(); i++){ 9 A[i]+=A[i-1]; 10 } 11 Lmax=A[L-1]; 12 Mmax=A[M-1]; 13 res=A[M+L-1]; 14 for(int i=L+M; i<A.size(); i++){ 15 Lmax=max(Lmax, A[i-M]-A[i-M-L]); 16 Mmax=max(Mmax, A[i-L]-A[i-L-M]); 17 res=max(res, max(Lmax+A[i]-A[i-M], Mmax+A[i]-A[i-L])); 18 } 19 return res; 20 } 21 };