You are given an array of integers arr and an integer target.
You have to find two non-overlapping sub-arrays of arr each with a sum equal target. There can be multiple answers so you have to find an answer where the sum of the lengths of the two sub-arrays is minimum.
Return the minimum sum of the lengths of the two required sub-arrays, or return -1 if you cannot find such two sub-arrays.
Example 1:
Input: arr = [3,2,2,4,3], target = 3 Output: 2 Explanation: Only two sub-arrays have sum = 3 ([3] and [3]). The sum of their lengths is 2.
Example 2:
Input: arr = [7,3,4,7], target = 7 Output: 2 Explanation: Although we have three non-overlapping sub-arrays of sum = 7 ([7], [3,4] and [7]), but we will choose the first and third sub-arrays as the sum of their lengths is 2.
Example 3:
Input: arr = [4,3,2,6,2,3,4], target = 6 Output: -1 Explanation: We have only one sub-array of sum = 6.
Constraints:
1 <= arr.length <= 1051 <= arr[i] <= 10001 <= target <= 108When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method is like trying every single possibility until you find the correct one. In this problem, it means checking every combination of two sections within the larger list to see if they both add up to the target sum.
Here's how the algorithm would work step-by-step:
def find_two_non_overlapping_sub_arrays_each_with_target_sum_brute_force(numbers, target): minimum_total_length = float('inf')
list_length = len(numbers)
for first_start_index in range(list_length):
for first_end_index in range(first_start_index, list_length):
first_sub_array = numbers[first_start_index:first_end_index+1]
if sum(first_sub_array) == target:
# Now find the second sub array in the remaining part of the list.
for second_start_index in range(list_length):
for second_end_index in range(second_start_index, list_length):
second_sub_array = numbers[second_start_index:second_end_index+1]
# Check if the sub arrays are non-overlapping and the second sums to the target
if sum(second_sub_array) == target:
if not (first_end_index < second_start_index or second_end_index < first_start_index):
continue
first_sub_array_length = len(first_sub_array)
second_sub_array_length = len(second_sub_array)
total_length = first_sub_array_length + second_sub_array_length
# We now compare total lengths
minimum_total_length = min(minimum_total_length, total_length)
if minimum_total_length == float('inf'):
return -1
else:
return minimum_total_lengthThe best way to solve this problem is to find the shortest possible sequences that add up to the target, then combine the two shortest ones. We do this by first finding the shortest sequences ending at each position, and then finding the shortest sequences starting at each position.
Here's how the algorithm would work step-by-step:
def find_two_non_overlapping_sub_arrays(numbers, target):
array_length = len(numbers)
shortest_length_ending_at = [float('inf')] * array_length
shortest_length_starting_at = [float('inf')] * array_length
# Find shortest subarrays ending at each index
current_sum = 0
start_index = 0
shortest_sub_array_length = float('inf')
for end_index in range(array_length):
current_sum += numbers[end_index]
while current_sum > target:
current_sum -= numbers[start_index]
start_index += 1
if current_sum == target:
shortest_sub_array_length = min(shortest_sub_array_length, end_index - start_index + 1)
shortest_length_ending_at[end_index] = shortest_sub_array_length
# Find shortest subarrays starting at each index
current_sum = 0
end_index = array_length - 1
shortest_sub_array_length = float('inf')
for start_index in range(array_length - 1, -1, -1):
current_sum += numbers[start_index]
while current_sum > target:
current_sum -= numbers[end_index]
end_index -= 1
if current_sum == target:
shortest_sub_array_length = min(shortest_sub_array_length, end_index - start_index + 1)
shortest_length_starting_at[start_index] = shortest_sub_array_length
minimum_combined_length = float('inf')
# Find the minimum combined length
for index in range(1, array_length):
minimum_combined_length = min(
minimum_combined_length,
shortest_length_ending_at[index - 1] + shortest_length_starting_at[index],
)
# Return -1 if no solution exists
if minimum_combined_length == float('inf'):
return -1
else:
return minimum_combined_length| Case | How to Handle |
|---|---|
| Null or empty input array | Return -1 immediately as no valid sub-arrays can exist. |
| Array size is less than two (cannot form two sub-arrays) | Return -1 since two non-overlapping sub-arrays are impossible. |
| No sub-arrays sum to the target | Return -1 if no two sub-arrays that satisfy target can be found. |
| Input array contains negative numbers | The sliding window or prefix sum approach must correctly handle negative values potentially resulting in shrinking/expanding windows. |
| Input array contains zero(s) | Zeroes can potentially form valid sub-arrays by themselves, or impact the sum calculation requiring careful handling in the sliding window/prefix sum. |
| Large array with a target sum occurring very late in the array | Ensure the solution doesn't have unnecessary iterations; potentially use early stopping or optimization within the search loops. |
| Integer overflow potential when calculating cumulative sums for large arrays or large numbers. | Use long data type for sum calculations and intermediate results to prevent overflow. |
| Multiple possible pairs of sub-arrays exist; find the minimal combined length. | Track the minimum length found so far and update it whenever a shorter valid combination is located. |