leetcode#689. Maximum Sum of 3 Non-Overlapping Subarrays

689. Maximum Sum of 3 Non-Overlapping Subarrays

Problem Description

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. Here is the code:

Analysis and Solution

A direct thought is that we can calculate each interval’s sum and choose every possible combinations and pick the maximum one. However, the time complexity is not consistent. So we should use dp to simplify it.

For each point, we calculate the max left interval and the max right interval and record the position of intervals. Then we pick a maximum sum as the result.

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

        vector<int> priors(n, 0);
        vector<int> posts(n, 0);
        priors[k] = 0;
        posts[n-2*k+1] = n-k+1;

        for (int i=k+1; i <= n-2*k+1; i++)
            priors[i] = sums[priors[i-1]] >= sums[i-k] ? priors[i-1] : i-k;
        for (int i=n-2*k; i >= k; i--)
            posts[i] = sums[posts[i+1]] > sums[i+k] ? posts[i+1] : i+k;

        int s = 0;
        vector<int> result;
        for (int i=k; i <= n-2*k; i++) {
            if (sums[i] + sums[priors[i]] + sums[posts[i]] > s) {
                s = sums[i] + sums[priors[i]] + sums[posts[i]];
                result = {priors[i], i, posts[i]};
            }
        }

        return result;
    }
};

However, this code costs about 700ms. Inspect it and in the first step the method to calculate the internal’s sum is too slow. A faster code is as below:

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

        vector<int> priors(n, 0);
        vector<int> posts(n, 0);
        priors[k] = 0;
        posts[n-2*k] = n-k;

        for (int i=k+1; i <= n-2*k; i++)
            priors[i] = sums[priors[i-1]] >= sums[i-k] ? priors[i-1] : i-k;
        for (int i=n-2*k-1; i >= k; i--)
            posts[i] = sums[posts[i+1]] > sums[i+k] ? posts[i+1] : i+k;

        int s = 0;
        vector<int> result;
        for (int i=k; i <= n-2*k; i++) {
            if (sums[i] + sums[priors[i]] + sums[posts[i]] > s) {
                s = sums[i] + sums[priors[i]] + sums[posts[i]];
                result = {priors[i], i, posts[i]};
            }
        }

        return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值