689.三个无重叠子数组的最大和
题目描述
思路
滑动窗口
使用3个大小为k的滑动窗口。设 s u m 1 sum_1 sum1为第一个滑动窗口的元素和,该滑动窗口从[0, k-1]开始; s u m 2 sum_2 sum2为第二个滑动窗口的元素和,该滑动窗口从[k, 2k-1]开始; s u m 3 sum_3 sum3位第三个滑动窗口的元素和,该滑动窗口从[2k, 3*k-1]开始。
同时向右滑动三个滑动窗口,每次滑动时,计算当前 m a x S u m 12 maxSum_{12} maxSum12与 s u m 3 sum_3 sum3之和。统计这一过程中的 m a x S u m 12 + s u m 3 maxSum_{12}+sum_3 maxSum12+sum3的最大值及对应位置。
而 m a x S u m 12 maxSum_{12} maxSum12可以由 m a x S u m 1 maxSum_1 maxSum1和 s u m 2 sum_2 sum2的和来求。
题目还要求使用最小字典序,因为是从左往右遍历,所以当且仅当元素和大于最大元素和时,才修改最大元素和以及对应位置。
Java实现
class Solution {
public int[] maxSumOfThreeSubarrays(int[] nums, int k) {
int[] ans = new int[3];
int sum1 = 0, maxSum1 = 0, maxSum1Idx = 0;
int sum2 = 0, maxSum12 = 0, maxSum12Idx1 = 0, maxSum12Idx2 = 0;
int sum3 = 0, maxTotal = 0;
for (int i = k * 2; i < nums.length; ++i) {
sum1 += nums[i - k * 2];
sum2 += nums[i - k];
sum3 += nums[i];
if (i >= k * 3 - 1) {
if (sum1 > maxSum1) {
maxSum1 = sum1;
maxSum1Idx = i - k * 3 + 1;
}
if (maxSum1 + sum2 > maxSum12) {
maxSum12 = maxSum1 + sum2;
maxSum12Idx1 = maxSum1Idx;
maxSum12Idx2 = i - k * 2 + 1;
}
if (maxSum12 + sum3 > maxTotal) {
maxTotal = maxSum12 + sum3;
ans[0] = maxSum12Idx1;
ans[1] = maxSum12Idx2;
ans[2] = i - k + 1;
}
sum1 -= nums[i - k * 3 + 1];
sum2 -= nums[i - k * 2 + 1];
sum3 -= nums[i - k + 1];
}
}
return ans;
}
}
Python实现
class Solution:
def maxSumOfThreeSubarrays(self, nums: List[int], k: int) -> List[int]:
ans = []
sum1, maxSum1, maxSum1Idx = 0, 0, 0
sum2, maxSum12, maxSum12Idx = 0, 0, ()
sum3, maxTotal = 0, 0
for i in range(k * 2, len(nums)):
sum1 += nums[i - k * 2]
sum2 += nums[i - k]
sum3 += nums[i]
if i >= k * 3 - 1:
if sum1 > maxSum1:
maxSum1 = sum1
maxSum1Idx = i - k * 3 + 1
if maxSum1 + sum2 > maxSum12:
maxSum12 = maxSum1 + sum2
maxSum12Idx = (maxSum1Idx, i - k * 2 + 1)
if maxSum12 + sum3 > maxTotal:
maxTotal = maxSum12 + sum3
ans = [*maxSum12Idx, i - k + 1]
sum1 -= nums[i - k * 3 + 1]
sum2 -= nums[i - k * 2 + 1]
sum3 -= nums[i - k + 1]
return ans