1477. Find Two Non-overlapping Sub-arrays Each With Target Sum
- Array
- Hash Table
- Binary Search
- Dynamic Programming
- Sliding Window
Intuition
Every element is positive, so as the right end of a window moves right, the left end only ever needs to move right too. That means a single sliding window visits every subarray whose sum is exactly target, and for each right index there is at most one such subarray.
Once we can enumerate target-sum subarrays left to right, pairing them is a prefix-minimum problem: when the window [l..r] hits target, the best partner is the shortest target-sum subarray that ends strictly before l. Keep a running array best[i] = shortest target-sum subarray ending at or before index i, and the partner is just best[l-1].
Approach
- Maintain
bestof lengthn, initialised to infinity, and a window sum. - For each
r, addarr[r], then shrink fromlwhile the sum exceedstarget. - If the sum equals
target:length = r - l + 1- if
l > 0andbest[l-1]is finite, update the answer withlength + best[l-1] - set
curBest = min(curBest, length)
- Set
best[r] = curBest(prefix minimum so far). - Return the answer, or
-1if it never got updated.
Every valid pair of non-overlapping subarrays has a right member; that right member is examined at step 3 with the optimal left partner, so the minimum found is exact.
Complexity
- Time: O(n), each index enters and leaves the window once
- Space: O(n) for the
bestarray
Edge Cases
- Single element array → at most one subarray, return
-1 - Only one target-sum subarray anywhere →
-1(Example 3) - Two target-sum subarrays that share an endpoint are overlapping and must not be paired; using
best[l-1]rather thanbest[l]enforces this - Overlapping candidates like
[7],[3,4],[7]where the shortest two are far apart (Example 2) targetlarger than the total sum → the window never matches,-1- Answer sum of lengths can reach
nexactly (e.g. two halves each summing to target)
Code
from typing import List
class Solution:
def minSumOfLengths(self, arr: List[int], target: int) -> int:
"""
1477. Find Two Non-overlapping Sub-arrays Each With Target Sum
Time: O(n)
Space: O(n)
"""
n = len(arr)
INF = float("inf")
# best[i] = shortest target-sum subarray ending at index <= i
best = [INF] * n
cur_best = INF
answer = INF
left = 0
window = 0
for right in range(n):
window += arr[right]
# all values positive, so shrinking from the left is monotone
while window > target:
window -= arr[left]
left += 1
if window == target:
length = right - left + 1
if left > 0 and best[left - 1] != INF:
answer = min(answer, length + best[left - 1])
cur_best = min(cur_best, length)
best[right] = cur_best
return -1 if answer == INF else answer/**
* 1477. Find Two Non-overlapping Sub-arrays Each With Target Sum
* Time: O(n)
* Space: O(n)
*/
class Solution {
public int minSumOfLengths(int[] arr, int target) {
int n = arr.length;
final int INF = Integer.MAX_VALUE;
// best[i] = shortest target-sum subarray ending at index <= i
int[] best = new int[n];
int curBest = INF;
int answer = INF;
int left = 0;
long window = 0;
for (int right = 0; right < n; right++) {
window += arr[right];
// all values positive, so shrinking from the left is monotone
while (window > target) {
window -= arr[left];
left++;
}
if (window == target) {
int length = right - left + 1;
if (left > 0 && best[left - 1] != INF) {
answer = Math.min(answer, length + best[left - 1]);
}
curBest = Math.min(curBest, length);
}
best[right] = curBest;
}
return answer == INF ? -1 : answer;
}
}