You are given an integer array nums
and an integer k
. Your task is to find three non-overlapping subarrays, each of length k
, such that their combined sum is maximized. You should return the starting indices of these three subarrays (0-indexed). If multiple solutions exist, return the lexicographically smallest one.
For example:
nums = [1,2,1,2,6,7,5,1], k = 2
The function should return [0, 3, 5]
because the subarrays [1, 2]
, [2, 6]
, and [7, 5]
yield the maximum sum. Note that although [2, 1]
could also be considered, the answer [1, 3, 5]
is lexicographically larger.
nums = [1,2,1,2,1,2,1,2,1], k = 2
The function should return [0, 2, 4]
.
Consider these constraints:
1 <= nums.length <= 2 * 10^4
1 <= nums[i] <= 2^16
1 <= k <= floor(nums.length / 3)
How would you implement an efficient algorithm to solve this problem?
A naive approach would involve iterating through all possible combinations of three non-overlapping subarrays of length k
and computing their sums. We can then find the combination that yields the maximum sum and return the starting indices. This approach is simple to understand but highly inefficient.
def max_sum_three_subarrays_brute_force(nums, k):
n = len(nums)
max_sum = 0
result = []
for i in range(n - 3 * k + 1):
for j in range(i + k, n - 2 * k + 1):
for l in range(j + k, n - k + 1):
sum1 = sum(nums[i:i+k])
sum2 = sum(nums[j:j+k])
sum3 = sum(nums[l:l+k])
current_sum = sum1 + sum2 + sum3
if current_sum > max_sum:
max_sum = current_sum
result = [i, j, l]
return result
Time Complexity: O(n^3), where n is the length of the input array nums
.
Space Complexity: O(1), as we only use a constant amount of extra space.
To improve efficiency, we can use a sliding window technique combined with dynamic programming to precompute the maximum sum subarrays from left to right and from right to left. This helps us to find the optimal solution in linear time.
k
.left
array where left[i]
stores the starting index of the maximum sum subarray of length k
in nums[0...i]
.right
array where right[i]
stores the starting index of the maximum sum subarray of length k
in nums[i...n-1]
.j
, we find the maximum sum by combining the maximum sum subarray to its left (using left[j-k]
), the sum of the middle subarray, and the maximum sum subarray to its right (using right[j+k]
).def max_sum_three_subarrays(nums, k):
n = len(nums)
sums = []
window_sum = sum(nums[:k])
sums.append(window_sum)
for i in range(k, n):
window_sum += nums[i] - nums[i - k]
sums.append(window_sum)
left = [0] * n
best = 0
for i in range(k, n - 2 * k + 1):
if sums[i] > sums[best]:
best = i
left[i] = best
right = [0] * n
best = n - k
for i in range(n - k - 1, 2 * k - 1, -1):
if sums[i] >= sums[best]:
best = i
right[i] = best
max_sum = 0
result = []
for j in range(k, n - 2 * k + 1):
left_index = left[j - k]
right_index = right[j + k]
current_sum = sums[left_index] + sums[j] + sums[right_index]
if current_sum > max_sum:
max_sum = current_sum
result = [left_index, j, right_index]
return result
Time Complexity: O(n), where n is the length of the input array nums
.
Space Complexity: O(n), due to the use of the left
, right
, and sums
arrays.
k
is larger than one-third of the array's length, there are no three non-overlapping subarrays of length k
, and again we return an appropriate error message or empty list. The problem statement specifies 1 <= k <= floor(nums.length / 3)
. So you should not need to test this case in an interview.nums = [1, 2, 1, 2, 6, 7, 5, 1]
k = 2
print(max_sum_three_subarrays(nums, k)) # Output: [0, 3, 5]
nums = [1, 2, 1, 2, 1, 2, 1, 2, 1]
k = 2
print(max_sum_three_subarrays(nums, k)) # Output: [0, 2, 4]