Given an array of positive integers nums
and a positive integer target
, return the minimal length of a subarray whose sum is greater than or equal to target
. If there is no such subarray, return 0
instead.
For example:
target = 7, nums = [2,3,1,2,4,3]
should return 2 because the subarray [4,3]
has the minimal length and sums to 7, satisfying the problem constraint.
target = 4, nums = [1,4,4]
should return 1 because the subarray [4]
has the minimal length and sums to 4, satisfying the problem constraint.
target = 11, nums = [1,1,1,1,1,1,1,1]
should return 0 because no subarray sums to 11.
Constraints:
1 <= target <= 10^9
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^4
Can you solve this problem in O(n) time? What about O(n log n)?
Given an array of positive integers nums
and a positive integer target
, find the minimal length of a contiguous subarray whose sum is greater than or equal to target
. If no such subarray exists, return 0.
A naive approach is to consider all possible subarrays and check if their sum is greater than or equal to the target. We keep track of the minimal length found so far.
i
from 0 to n-1
.j
from i
to n-1
.nums[i...j]
.def min_subarray_len_brute_force(target: int, nums: list[int]) -> int:
min_len = float('inf')
n = len(nums)
for i in range(n):
for j in range(i, n):
sub_array_sum = sum(nums[i:j+1])
if sub_array_sum >= target:
min_len = min(min_len, j - i + 1)
return min_len if min_len != float('inf') else 0
O(n^2) due to the nested loops.
O(1) as we only use a constant amount of extra space.
A more efficient approach is to use the sliding window technique. We maintain a window (subarray) and adjust its start and end to find the minimal length subarray that satisfies the condition.
start
and end
, to 0.current_sum
to 0 and min_len
to infinity.end
is less than the length of the array.nums[end]
to current_sum
.current_sum
is greater than or equal to the target:
min_len
with the minimum of min_len
and end - start + 1
.nums[start]
from current_sum
.start
.end
.min_len
is still infinity, return 0; otherwise, return min_len
.def min_subarray_len_sliding_window(target: int, nums: list[int]) -> int:
start = 0
end = 0
current_sum = 0
min_len = float('inf')
n = len(nums)
while end < n:
current_sum += nums[end]
while current_sum >= target:
min_len = min(min_len, end - start + 1)
current_sum -= nums[start]
start += 1
end += 1
return min_len if min_len != float('inf') else 0
O(n) because each element is visited at most twice (once by start
and once by end
).
O(1) as we only use a constant amount of extra space.
min_len
check.target = 7, nums = [2, 3, 1, 2, 4, 3]
The sliding window expands and contracts:
[2]
, sum = 2[2, 3]
, sum = 5[2, 3, 1]
, sum = 6[2, 3, 1, 2]
, sum = 8 >= 7. min_len = 4
. Shrink.[3, 1, 2]
, sum = 6 < 7. Stop shrinking.[3, 1, 2, 4]
, sum = 10 >= 7. min_len = 4
. Shrink.[1, 2, 4]
, sum = 7 >= 7. min_len = 3
. Shrink.[2, 4]
, sum = 6 < 7. Stop shrinking.[2, 4, 3]
, sum = 9 >= 7. min_len = 3
. Shrink.[4, 3]
, sum = 7 >= 7. min_len = 2
. Shrink.[3]
, sum = 3 < 7. Stop shrinking.Final Result: 2