689. Maximum Sum of 3 Non-Overlapping Subarrays

本文探讨了在给定正整数数组中寻找三个不重叠子数组以获得最大和的问题,每个子数组大小固定,通过动态规划方法确定最佳起始位置。介绍了算法思路,给出C++实现代码,并解释了如何确保解的字典序最小。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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).

 

Approach #1: DP. [C++]

class Solution {
public:
    vector<int> maxSumOfThreeSubarrays(vector<int>& nums, int k) {
        int len = nums.size();
        vector<int> sum = {0}, posLeft(len, 0), posRight(len, len-k);
        for (int i : nums) sum.push_back(sum.back()+i);
        for (int i = k, total = sum[k] - sum[0]; i < len; ++i) {
            if (sum[i+1] - sum[i+1-k] > total) {
                total = sum[i+1] - sum[i+1-k];
                posLeft[i] = i + 1 -k;
            } else 
                posLeft[i] = posLeft[i-1];
        }
        
        for (int i = len-k-1, total = sum[len] - sum[len-k]; i >= 0; --i) {
            if (sum[i+k] - sum[i] > total) {
                total = sum[i+k] - sum[i];
                posRight[i] = i;
            } else 
                posRight[i] = posRight[i+1];
        }
        
        int maxsum = 0;
        vector<int> ans;
        for (int i = k; i <= len-2*k; ++i) {
            int l = posLeft[i-1], r = posRight[i+k];
            int tot = (sum[i+k] - sum[i]) + (sum[l+k] - sum[l]) + (sum[r+k] - sum[r]);
            if (tot > maxsum) {
                maxsum = tot;
                ans = {l, i, r};
            }
        }
        
        return ans;
    }
};

  

Analysis:

The question asks for three non-overlapping intervals with maximum sum of all 3 intervals. If the middle interval is [i, i+k-1], where k <= i <= n-2k, the left intervals. If the middle interval is [i, i+k-1], where k <= i <= n - 2k, the left interval has to be in subrange [0, i-1], ans the right interval is from subrange [i+k, n-1].

 

So the following solution is based on DP.

 

posLeft[i] is the starting index for the left interval in range [0, i];

posRight[i] is the strating index for the right interval in range [i, n-1];

Then we test every possible strating index og middle interval, i.e. k <= i <= n-2k, ans we can get the corresponding left and right max sum intervals easily from DP. and the run time is O(n).

 

Caution. In order to get lexicgraphical smallest order, when there are tow intervals with equal max sum, always select the left most one. So in the code. the is condition is ">=" for right interval due to backward searching, and ">" for left interval. 

 

Reference:

https://leetcode.com/problems/maximum-sum-of-3-non-overlapping-subarrays/discuss/108231/C%2B%2BJava-DP-with-explanation-O(n)

 

转载于:https://www.cnblogs.com/ruruozhenhao/p/10524974.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值