Leetcode K长连续子段和

对于最长连续子段问题,其思路是遍历:

  • 初始化sum=0
  • 每次sum+=a[i]  更新max   
  • 如果sum<0  那么 sum=0  从下一个数字开始加起

但如果要求连续子段的长度大于等于K:

题目描述

给出一个n个数字的序列a_1,a_2,\dots a_na1​,a2​,…an​,你想知道所有长度大于等于k的连续子段中,子段数字和最大可以是多少。

示例1

输入

3,2,[2,3,4]

输出

9

【思路】

dp[i]表示以i结尾的连续子段中,长度大于等于K的最大子段和。

那么对于i+1的求解,即以i+1结尾len>=k 的最大连续子段和分为两种情况:

  1. 长度=k:那么其子段和为 sum[i+1]-sum[i+1-k]    (其中sum存放数列的前n项和,差即区间的和)
  2. 长度>k:那么一定是与前一个数字的所求,组合成连续子段达到最大,即在i的基础上   dp[i]+a[i+1]

这两种情况取较大值,即:

dp[i+1]=max(dp[i]+a[i+1],sum[i+1]-sum[i+1-k])

【实现代码】

 long long solve(int n, int k, vector<int>& a) {
      vector<long long> sum(n+1,0);
      vector<long long> dp(n+1,0);
      for(int i=1;i<=n;i++)      //计算数列前N项和
          sum[i]=sum[i-1]+a[i-1];
      dp[k]=sum[k];   //从第k项开始 小于K一定无法达到长度K要求
      long long ans=dp[k];
      for(int i=k+1;i<=n;i++)
      {
          dp[i]=max(dp[i-1]+a[i-1],sum[i]-sum[i-k]);
          ans=max(ans,dp[i]);
      }
      return ans;
        
    }

 

由此可见,最大k长连续子段和问题,其本质是最大连续子段和问题的拓展,那么最大连续字段和问题的动态规划思路为:

dp[i]=max(dp[i-1]+a[i],a[i])

即:

  • a[i]与前面组合成子段
  • a[i]自己单独成为一个子段

两者取较大值

 

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 撸撸猫 设计师:C马雯娟 返回首页