📅  最后修改于: 2023-12-03 15:28:36.173000             🧑  作者: Mango
给定一个整数数组 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)$。