You are given a 0-indexed array nums
and an integer target
.
A 0-indexed array infinite_nums
is generated by infinitely appending the elements of nums
to itself.
Return the length of the shortest subarray of the array infinite_nums
with a sum equal to target
. If there is no such subarray return -1
.
Example 1:
Input: nums = [1,2,3], target = 5 Output: 2 Explanation: In this example infinite_nums = [1,2,3,1,2,3,1,2,...]. The subarray in the range [1,2], has the sum equal to target = 5 and length = 2. It can be proven that 2 is the shortest length of a subarray with sum equal to target = 5.
Example 2:
Input: nums = [1,1,1,2,3], target = 4 Output: 2 Explanation: In this example infinite_nums = [1,1,1,2,3,1,1,1,2,3,1,1,...]. The subarray in the range [4,5], has the sum equal to target = 4 and length = 2. It can be proven that 2 is the shortest length of a subarray with sum equal to target = 4.
Example 3:
Input: nums = [2,4,6,8], target = 3 Output: -1 Explanation: In this example infinite_nums = [2,4,6,8,2,4,6,8,...]. It can be proven that there is no subarray with sum equal to target = 3.
Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= 105
1 <= target <= 109
When 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 possible option until you find the right one. For this problem, we'll explore all possible continuous sections of numbers to see which one adds up to the target with the fewest numbers.
Here's how the algorithm would work step-by-step:
def min_subarray_infinite_array_brute_force(numbers, target): minimum_subarray_length = float('inf')
array_length = len(numbers)
for start_index in range(array_length):
for end_index in range(start_index, array_length):
current_subarray = numbers[start_index:end_index+1]
current_sum = sum(current_subarray)
if current_sum == target:
current_subarray_length = end_index - start_index + 1
# We need to consider the infinite array.
minimum_subarray_length = min(minimum_subarray_length, current_subarray_length)
elif current_sum < target:
number_of_repeats = (target - current_sum) // sum(numbers)
current_sum += sum(numbers) * number_of_repeats
current_subarray_length = (end_index - start_index + 1) + array_length * number_of_repeats
if current_sum == target:
# Update minimum length if we find a better one
minimum_subarray_length = min(minimum_subarray_length, current_subarray_length)
else:
remaining_target = target - current_sum
temp_sum = 0
temp_length = 0
for i in range(array_length):
temp_sum += numbers[i]
temp_length += 1
if temp_sum == remaining_target:
current_subarray_length += temp_length
minimum_subarray_length = min(minimum_subarray_length, current_subarray_length)
break
elif temp_sum > remaining_target:
break
if minimum_subarray_length == float('inf'):
return -1
else:
return minimum_subarray_length
Imagine the array repeats forever. The key is to realize we only need to consider a portion of this infinite array. We find the smallest chunk that adds up to the target value (or a multiple), then we use a sliding window to optimize.
Here's how the algorithm would work step-by-step:
def minimum_size_subarray_infinite(numbers, target):
array_length = len(numbers)
total_sum = sum(numbers)
if total_sum == 0:
return -1 if target > 0 else 0
if target == 0:
return 0
repetitions = target // total_sum
remainder = target % total_sum
if remainder == 0:
return array_length * repetitions
# Find the smallest subarray that sums to the remainder.
start_index = 0
end_index = 0
window_sum = 0
min_length = float('inf')
# Sliding window to find the minimum length subarray.
while start_index < 2 * array_length:
while end_index < 2 * array_length and window_sum < remainder:
window_sum += numbers[end_index % array_length]
end_index += 1
# Update min_length when the window_sum is >= remainder.
while window_sum >= remainder:
min_length = min(min_length, end_index - start_index)
window_sum -= numbers[start_index % array_length]
start_index += 1
if min_length == float('inf'):
return -1
# The final answer is the minimum length plus repetitions of the array.
return min_length + repetitions * array_length
Case | How to Handle |
---|---|
Empty input array (nums) | Return -1 immediately as there are no elements to form a subarray. |
Target is smaller than any number in the array. | The sliding window algorithm will never find a valid subarray, resulting in returning -1 at the end. |
Target is zero. | Return -1 since all numbers are positive, no subarray can sum to zero. |
nums array contains only one element and target is not a multiple of that element. | The algorithm will either find a subarray that sums to target or it will not, returning -1 accordingly. |
Sum of all elements in nums is greater than target, but no subarray sums to target. | The sliding window approach correctly searches for a subarray, and returns -1 when none is found |
Integer overflow if target or intermediate sums become too large. | Use long data type for sums to avoid integer overflow. |
Target is a very large number, requiring multiple iterations of nums to achieve the target sum. | Calculate how many complete repetitions of nums are needed, and then use the sliding window approach on the remaining target. |
Target is equal to the sum of all elements in nums. | The minimum subarray size is the length of nums. |