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 }