[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).Thought process:
Dynamic programming.
- Create an array of sums of windows of size k. This array's length will be nums.length - k + 1, because an array can have this many choices of windows.
- Iterate through the windows and find the index of the window with the max sum to the left and to the right.
- Iterate through the windows again and get and three windows with max sum.
Solution:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | class Solution { public int[] maxSumOfThreeSubarrays(int[] nums, int k) { int[] win = new int[nums.length - k + 1]; int sum = 0; for (int i = 0; i < nums.length; i++) { sum += nums[i]; if (i >= k) { sum -= nums[i - k]; } if (i >= k - 1) { win[i - (k - 1)] = sum; } } int j = 0; int[] left = new int[win.length]; for (int i = 0; i < win.length; i++) { if (win[i] > win[j]) { j = i; } left[i] = j; } j = win.length - 1; int[] right = new int[win.length]; for (int i = win.length - 1; i >= 0; i--) { if (win[i] >= win[j]) { j = i; } right[i] = j; } int[] max = new int[]{ -1, -1, -1 }; for (int b = k; b < win.length - k; b++) { int a = left[b - k]; int c = right[b + k]; if (max[0] == -1 || win[a] + win[b] + win[c] > win[max[0]] + win[max[1]] + win[max[2]]) { max[0] = a; max[1] = b; max[2] = c; } } return max; } } |
Time complexity: O(n).
your right function wrong dude.
ReplyDeleteif (win[i] > win[j]) {
j = i;
}
should be
if (win[i] >= win[j]) {
j = i;
}
since the answer is
If there are multiple answers, return the lexicographically smallest one.
Good point! Thanks for pointing out.
Deletewhat if they asked for m subarray in general?
ReplyDelete