leetcode:求这两个连续子数组元素最大之和为多少

Given an array A of non-negative integers,return the maximum sum of elements in two 
non-overlapping(contiguous)subarrays,which have lengths L and M.(For clarification,the L-
length subarrays could occur before or after the M-length subarrays.)
Formally,return the largest V for which V=(A[i]+A[i+1]+...+A[i+L-1]+(A[j]+A[j+1]+...+A[j+M-1]
) and either.
(1) 0 <= i < i+L-1 < j+M-1 < A.length,or 0 <= j < j+M-1 < i < i+L-1 < A.length.

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.

题目大意:
给定一个非负数组A,以及长度为L和M,找出不重叠且长度分别为L和M的两个连续子数组,对顺序没有要求,
求这两个子数组最大之和为多少.

解题思路:
方法1:
利用sliding window维持两个L和W,直接枚举.超出时间限制

方法2:
首先建立数组的前n项累加和,分别以L在前M在后,M在前L在后两种方式,滑动窗口,每次移动一格.然后定义Lmax
为在最后M个元素之前的长度为L的子数组元素的最大之和,同样道理Mmax表示为在最后L个元素之前的长度为M的
子数组元素的最大之和.结果ans初始化为L+M的个元素之和,然后枚举整个数组,从L+M开始进行遍历,先更新
Lmax和Mmax,其中:Lmax表示更新A[i-M]-A[i-M-L],Mmax表示更新A[i-L]-A[i-M-L].然后再取
Lmax+A[i]-A[i-M]和Mmax+A[i]-A[i-L]之间的最大值用来更新ans.

C++语言实现

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Solution {
public:
    int maxSumTwoNoOverlap(vector<int>& A,int L,int M){
        if(A.size()<L+M) return 0;
        int ans=0;
        for(int i=0;i<A.size()-L+1;++i){
            int lm=0,lmax=0;
            while(lm<L){
                lmax+=A[i+lm];
                lm++;
            }
            int rmax=0;
            if(i-M>=0){
                for(int j=0;j<=i-M;++j){
                    //cout<<i<<" "<<j<<endl;
                    int r1=0,tmp=0;
                    while(r1<M){
                        tmp+=A[j+r1];
                        r1++;
                    }
                    rmax=max(tmp,rmax);
                }
            }
            if(A.size()-i-L>=0){
                for(int j=i+L;j<=A.size()-M;++j){
                    //cout<<i<<" "<<j<<endl;
                    int r1=0,tmp=0;
                    while(r1<M){
                        tmp+=A[j+r1];
                        r1++;
                    }
                    rmax=max(tmp,rmax);
                }
            } 
            ans=max(ans,lmax+rmax); 
        }
        return ans;
    }
    int maxSumTwoNoOverlapOne(vector<int>& A,int L,int M){
        for(int i=1;i<A.size();++i){
            A[i]+=A[i-1];
        }

        int ans=A[L+M-1],Lmax=A[L-1],Mmax=A[M-1];
        //分别以L在前M在后,M在前L在后两种方式,滑动窗口,每次移动一格
        for(int i=L+M;i<A.size();++i){
            Lmax=max(Lmax,A[i-M]-A[i-M-L]);
            Mmax=max(Mmax,A[i-L]-A[i-M-L]);
            ans=max(ans,max(Lmax+A[i]-A[i-M],Mmax+A[i]-A[i-L]));
        }
        return ans;
    }
};

int main(int argc,char* argv[]){
    vector<int> A={3,8,1,3,2,1,8,9,0};
    int L=3,M=2;
    printf("%d\n",Solution().maxSumTwoNoOverlap(A,L,M));
    printf("%d\n",Solution().maxSumTwoNoOverlapOne(A,L,M));
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路上的追梦人

您的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值