首页 > 试题广场 >

k长连续子段和

[编程题]k长连续子段和
  • 热度指数:1166 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给出一个n个数字的序列,你想知道所有长度大于等于k的连续子段中,子段数字和最大可以是多少。

连续子段指的是序列中一段连续的数字。子段数字和指的是子段中所有数字相加的和。
示例1

输入

5,2,[-4,4,-2,1,-3]

输出

9

说明

因为要选的子段的长度必须大于等于2,所以最优的选择是选择[4,-2,1],得到的答案为3 

备注:

第一个参数n代表序列中的数字个数

第二个参数代表连续子段的长度要大于等于

第三个参数a包含个元素,代表给出的序列

只有我一个人觉得示例给的有问题吗?
发表于 2021-08-14 14:14:49 回复(1)

class Solution:
    def solve(self , n , k , a ):
        # write code here
        S = [a[0]]*n
        for i in range(1, len(a)):
            S[i] = S[i-1] + a[i]
        dp = S[:]
        for i in range(k, len(a)):
            dp[i] = max(dp[i-1] + a[i], S[i] - S[i-k])
        return max(dp[k-1:])


编辑于 2020-07-29 16:39:30 回复(0)
dp[i]表示以“第i个数字结尾”的子段最大和
sum[i]表示从第1个数字到第i个数字的和(sum[i]-sum[i-k]自然就表示,从第i-k+1到i,共k个数的和)
dp[i]可以选择继承--->dp[i-1]+a[i-1],也可以“另起炉灶”--->dp[i]=sum[i]-sum[i-k]
故dp[i]=max(dp[i-1]+a[i-1],sum[i]-sum[i-k])

1.代码写的不规范,见谅!😥
2.其实不用构造sum数组,毕竟sum数组占了n的空间,但用的话确实更加直观。
class Solution {
public:
    /**
     * k长连续子段和
     * @param n int整型 
     * @param k int整型 
     * @param a int整型vector 
     * @return long长整型
     */
    long long solve(int n, int k, vector<int>& a) {
        // write code here
        typedef long long ll;
        vector<ll> sum(n+1,0);
        vector<ll> dp(n+1,0);
        //构造sum数组
        for(int i=1;i<=n;i++)
            sum[i]=sum[i-1]+a[i-1];
        //dp从k开始,若i<k,第i个数字显然不能作为结尾
        dp[k]=sum[k];
        ll result=dp[k];
        for(int i=k+1;i<=n;i++){
            dp[i]=max(dp[i-1]+a[i-1],sum[i]-sum[i-k]);
            result=max(result,dp[i]);
        }
        
        return result;
    }
};

发表于 2020-07-12 09:49:55 回复(0)
一开始用动态规范模板,同时对n和k进行递推,发现会内存超限。
其实只用对N进行递推就行了
    solve(n, k, a: Array<number>) {
        let dp = new Array(n + 1).fill(0);
        let sum = 0;
        //先初始化
        for (let i = 1; i <= k; i++) {
            dp[i] = dp[i - 1] + a[i - 1];
        }
        let result = dp[k];
        for (let i = k + 1; i <= n; i++) {
            sum += a[i - k - 1];
            if (sum < 0) {
                //舍弃掉前半段,只留k个元素
                dp[i] = dp[i - 1] + a[i - 1] - sum;
                sum = 0;
            } else {
                dp[i] = dp[i - 1] + a[i - 1];
            }
            result = Math.max(dp[i], result);
        }
        return result;
    }


发表于 2020-06-24 17:42:18 回复(0)
f[i] = max(f[i-1]+a[i-1], s[i]-s[i-k]);
最长字段连续和的变种,稍微改下即可
发表于 2020-04-22 11:15:02 回复(1)

问题信息

难度:
5条回答 3741浏览

热门推荐

通过挑战的用户

查看代码