[leetcode]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).

 

思路:

We need to find 3 subarrays

Let's say if I can find the 2nd subarray , then find the largest subarray on both left side and right side, problem solved.

 

代码:

 1 class Solution {
 2     public int[] maxSumOfThreeSubarrays(int[] nums, int k) {
 3         int[] sum = new int[nums.length]; // sum[i] = num[i] + nums[i+1]...+nums[i+k-1];
 4         int[] lef = new int[nums.length]; // lef[i] = before i, the max sum[];
 5         int[] rig = new int[nums.length];   // rif[i] = after i, the max sum[];
 6         int[] IndexL = new int[nums.length];
 7         int[] IndexR = new int[nums.length];
 8         int total = 0;
 9         
10         //build sum[]
11         for(int i=0; i<nums.length; i++){
12             if(i <= k-1){
13                 total += nums[i];
14             }else{
15                 total = total + nums[i] - nums[i-k];
16             }
17             if(i-k+1>=0){
18                 sum[i-k+1] = total;
19             }
20         }
21         
22         int max = 0;
23         //build lef[]
24         for(int i=0; i<=nums.length-k; i++){ //i-k+1 < nums.length -> j < n-k+1
25             if(sum[i] > max){
26                 max = sum[i];
27                 lef[i] = max;
28                 IndexL[i] = i;
29             }else{
30                 lef[i] = lef[i-1];
31                 IndexL[i] = IndexL[i-1];
32             }
33         }
34         max = 0;
35         //build rig[]
36         for(int i=nums.length-k; i>=0; i--){
37             if(sum[i] >= max){
38                 max = sum[i];
39                 rig[i] = max;
40                 IndexR[i] = i;
41             }else{
42                 rig[i] = rig[i+1];
43                 IndexR[i] = IndexR[i+1];
44             }
45         }
46         // find 2rd subarray;
47         total = 0;
48         int ret = 0;
49         int[] ans = new int[3];
50         for(int i=k; i<=nums.length-2*k; i++){ // since no overlap so start with k;
51             total = sum[i] + lef[i-k] + rig[i+k]; //i+k <= nums.length-k
52             if(total > ret){
53                 ret = total;
54                 total = 0;
55                 ans[0] = IndexL[i-k];
56                 ans[1] = i;
57                 ans[2] = IndexR[i+k];
58             }
59         }
60         return ans;
61     }
62 }

 

转载于:https://www.cnblogs.com/liuliu5151/p/9810115.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值