LeetCode 689. Maximum Sum of 3 Non-Overlapping Subarrays

45 阅读2分钟

🔗 leetcode.com/problems/ma…

题目

  • 给一个数组,和一个数字 k
  • 求三个不相交的,且长度为 k 的子数组,使得其 sum 最大
  • 返回这三个子数组的起始位置的下标,字典序最小的

思路

  • dp
  • 第一轮 dp,计算并保留到当前位置为止,一个长度为 k 的子数组的最大值,以及对应的起始下标。递推公式为,dp0[i] = max(dp0[i - 1], presum[i] - presum[i - k])
  • 第二轮 dp,计算并保留到当前位置为止,两个长度为 k 且不相交的子数组的最大值,以及对应的起始下标。递推公式为 dp1[i] = max(dp1[i - 1], presum[i] - presum[i - k] + dp0[i - k])
  • 第三轮 dp,计算并保留到当前位置为止,三个长度为 k 且不相交的子数组的最大值,以及对应的起始下标。递推公式为 dp2[i] = max(dp2[i - 1], presum[i] - presum[i - k] + dp1[i - k])

代码

class Solution {
public:
    vector<int> maxSumOfThreeSubarrays(vector<int>& nums, int k) {
        vector<int> presum(nums.size());
        presum[0] = nums[0];
        for (int i = 1; i < nums.size(); i++) {
            presum[i] = presum[i-1] + nums[i];
        }

        vector<int> dp0(nums.size());
        vector<int> index0(nums.size());
        dp0[k - 1] = presum[k - 1];
        index0[k - 1] = 0;
        for (int i = k; i < nums.size(); i++) {
            if (dp0[i - 1] >= presum[i] - presum[i - k]) {
                dp0[i] = dp0[i - 1];
                index0[i] = index0[i - 1];
            } else {
                dp0[i] = presum[i] - presum[i - k];
                index0[i] = i - k + 1;
            }
        }

        vector<int> dp1(nums.size());
        vector<vector<int>> index1(nums.size());
        dp1[2* k - 1] = presum[2 * k - 1];
        index1[2*k -1] = {0, k};
        for (int i = 2*k; i < nums.size(); i++) {
            if (dp1[i - 1] >= presum[i] - presum[i - k] + dp0[i - k]) {
                dp1[i] = dp1[i - 1];
                index1[i] = index1[i - 1];
            } else {
                dp1[i] = presum[i] - presum[i - k] + dp0[i - k];
                index1[i] = {index0[i - k], i - k + 1};
            }
        }

        vector<int> dp2(nums.size());
        vector<vector<int>> index2(nums.size());
        dp2[3*k - 1] = presum[3*k -1];
        index2[3*k -1] = {0, k, 2*k};
        int maxsum = dp2[3*k - 1];
        int index = 3*k -1;
        for (int i = 3*k; i < nums.size(); i++) {
            if (dp2[i-1] >= presum[i] - presum[i - k] + dp1[i - k]) {
                dp2[i] = dp2[i-1];
                index2[i] = index2[i-1];
            } else {
                dp2[i] = presum[i] - presum[i - k] + dp1[i - k];
                index2[i] = {index1[i-k][0], index1[i-k][1], i-k+ 1};
            }
            if (maxsum < dp2[i]) {
                maxsum = dp2[i];
                index = i;
            }
        }
        return index2[index];
    }
};