689. Maximum Sum of 3 Non-Overlapping Subarrays

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;
        }
    };


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值