📜  长度最多为 K 的非重叠子数组的最大和(1)

📅  最后修改于: 2023-12-03 15:28:36.173000             🧑  作者: Mango

长度最多为 K 的非重叠子数组的最大和

给定一个整数数组 nums 和一个整数 k,你需要找到长度最多为 k 的非重叠子数组的最大和。

问题描述

给定一个长度为 n 的整数数组 nums 和一个整数 k,你需要找到长度最多为 k 的非重叠子数组的最大和。

一个子数组的定义是一个连续的一段数字。重叠子数组是两个或多个子数组的交集,非重叠子数组则不会存在交集。

解题思路

首先我们需要注意到这是一个非重叠子数组的问题,因此我们需要将原先的问题转化一下:在不重叠的情况下,找到 k 个子数组的和最大。

我们可以使用动态规划的思想来解决这个问题。我们定义 f(i, j) 为:在前 i 个元素中选择 j 个不重叠的子数组的最大和。

考虑到不能选取相邻的元素,因此我们需要记录一个变量 last,表示上一个被选择的元素下标。

状态转移方程为:$$ f(i, j) = \max{ f(i-1, j), f(last, j-1) + \sum\limits_{k=last+1}^{i}a_k } $$

其中 $a_k$ 表示第 k 个元素的值,$\sum\limits_{k=last+1}^{i}a_k$ 表示 last 到 i 中间这段子数组的和。

最终的答案为 $f(n, k)$。

代码实现
def maxSumOfNonOverlapSubarrays(nums: List[int], k: int) -> int:
    n = len(nums)
    f = [[float("-inf")] * (k+1) for i in range(n+1)]
    f[0][0] = 0
    for i in range(1, n+1):
        f[i][0] = 0
        for j in range(1, k+1):
            f[i][j] = f[i-1][j]
            if i-j >= 0:
                s = 0
                for x in range(i-1, j-2, -1):
                    s += nums[x]
                    f[i][j] = max(f[i][j], f[x][j-1] + s)
    return f[n][k]
复杂度分析

时间复杂度:$O(nk^2)$,其中 n 是数组 nums 的长度,k 是限制的子数组的个数。

空间复杂度:$O(nk)$。