1031. 两个非重叠子数组的最大和
给你一个整数数组 nums
和两个整数 firstLen
和 secondLen
,请你找出并返回两个非重叠 子数组 中元素的最大和,长度分别为 firstLen
和 secondLen
。
长度为 firstLen
的子数组可以出现在长为 secondLen
的子数组之前或之后,但二者必须是不重叠的。
子数组是数组的一个 连续 部分。
示例 1:
输入:nums = [0,6,5,2,2,5,1,9,4], firstLen = 1, secondLen = 2
输出:20
解释:子数组的一种选择中,[9] 长度为 1,[6,5] 长度为 2。
题解

代码
class Solution {
public:
int maxSumTwoNoOverlap(vector &nums, int firstLen, int secondLen) {
int ans = 0, n = nums.size(), s[n + 1]; // 定义变量
s[0] = 0;
partial_sum(nums.begin(), nums.end(), s + 1); // partial_sum 函数计算 nums 的前缀和
// 定义一个 lambda 函数对象,用于计算两个相离的子数组的最大和
auto f = [&](int firstLen, int secondLen) {
int maxSumA = 0;
for (int i = firstLen + secondLen; i <= n; ++i) { // 遍历 s 数组,计算 A、B 两个子数组的最大和
// 计算 A 子数组的最大和
maxSumA = max(maxSumA, s[i - secondLen] - s[i - secondLen - firstLen]);
// 计算 A、B 两个子数组的总和,并更新最大值
ans = max(ans, maxSumA + s[i] - s[i - secondLen]);
}
};
// 分别计算左 a 右 b 和左 b 右 a 两个方案的最大和,并取两个方案的最大值
f(firstLen, secondLen); // 左 a 右 b
f(secondLen, firstLen); // 左 b 右 a
return ans; // 返回最大和
}
};