In a given array nums
of positive integers, find three non-overlapping subarrays with maximum sum.
Each subarray will be of size k
, and we want to maximize the sum of all 3*k
entries.
Return the result as a list of indices representing the starting position of each interval (0-indexed). If there are multiple answers, return the lexicographically smallest one.
Example:
Input: [1,2,1,2,6,7,5,1], 2 Output: [0, 3, 5] Explanation: Subarrays [1, 2], [2, 6], [7, 5] correspond to the starting indices [0, 3, 5]. We could have also taken [2, 1], but an answer of [1, 3, 5] would be lexicographically larger.
Note:
-
nums.length
will be between 1 and 20000. -
nums[i]
will be between 1 and 65535. -
k
will be between 1 and floor(nums.length / 3).
分析
求三个不相交的长度为k的子数组的最大和。可先求出每个长度为k的子数组的和w[0...nums.size()-k]。我们要求的是max{w[i]+w[j]+w[z]},其中i+k<=j, j+k<=z.对于某个固定的j,max{w[i]+w[j]+w[z]}取决于j左边的不相交的最大的w[i],和j右边的不相交的最大的w[z].因此,对每个j,求出每个j左右两边最大的w[i]和w[z].我们就能得到max{w[i]+w[j]+w[z]},其中i+k<=j, j+k<=z.
代码
class Solution { public: vector<int> maxSumOfThreeSubarrays(vector<int>& nums, int K) { int W[nums.size() - K + 1]; int sum = 0; for (int i = 0; i < nums.size(); i++) { sum += nums[i]; if (i >= K) sum -= nums[i-K]; if (i >= K-1) W[i-K+1] = sum; } int left[nums.size() - K + 1]; int best = 0; for (int i = 0; i < nums.size() - K + 1; i++) { if (W[i] > W[best]) best = i; left[i] = best; } int right[nums.size() - K + 1]; best = nums.size() - K; for (int i = nums.size() - K; i >= 0; i--) { if (W[i] >= W[best]) best = i; right[i] = best; } int a[3] = {-1, -1, -1}; vector<int> ans(a,a+3); for (int j = K; j <nums.size() - K + 1 - K; j++) { int i = left[j - K], k = right[j + K]; if (ans[0] == -1 || W[i] + W[j] + W[k] > W[ans[0]] + W[ans[1]] + W[ans[2]]) { ans[0] = i; ans[1] = j; ans[2] = k; } } return ans; } };