You are 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.
A subarray is a contiguous non-empty sequence of elements within an array.
Example 1:
Input: target = 10, nums = [2,1,5,1,5,3]
Output: 3Explanation: The subarray [5,1,5] has the minimal length under the problem constraint.
Example 2:
Input: target = 5, nums = [1,2,1]
Output: 0Constraints:
1 <= nums.length <= 100,0001 <= nums[i] <= 10,0001 <= target <= 1,000,000,000Follow up: If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log(n)).
Before attempting this problem, you should be comfortable with:
The most straightforward approach is to check every possible subarray. For each starting index, we expand the subarray until the sum reaches or exceeds the target, then record the length. Since all numbers are positive, once we hit the target we can stop expanding from that starting point.
res to infinity.i from 0 to n-1:curSum = 0.j from i to n-1, adding nums[j] to curSum.curSum >= target, update res with j - i + 1 and break.0 if res is still infinity, otherwise return res.class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
n = len(nums)
res = float("inf")
for i in range(n):
curSum = 0
for j in range(i, n):
curSum += nums[j]
if curSum >= target:
res = min(res, j - i + 1)
break
return 0 if res == float("inf") else resSince all elements are positive, we can use a sliding window approach. We expand the window by moving the right pointer to increase the sum. Once the sum meets or exceeds the target, we try to shrink the window from the left to find the minimum length. This works because removing elements from the left will only decrease the sum, and we want the smallest window that still satisfies the condition.
l = 0, total = 0, and res = infinity.r from 0 to n-1:nums[r] to total.total >= target:res with the minimum of res and r - l + 1.nums[l] from total and increment l.0 if res is infinity, otherwise return res.class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
l, total = 0, 0
res = float("inf")
for r in range(len(nums)):
total += nums[r]
while total >= target:
res = min(r - l + 1, res)
total -= nums[l]
l += 1
return 0 if res == float("inf") else resWe can precompute prefix sums so that the sum of any subarray from index i to j is prefixSum[j+1] - prefixSum[i]. Since all numbers are positive, the prefix sum array is strictly increasing. For each starting index i, we can binary search for the smallest ending index j where the subarray sum is at least target.
prefixSum[i] represents the sum of the first i elements.i:[i, n] to find the smallest j where prefixSum[j+1] - prefixSum[i] >= target.res with j - i + 1.res % (n + 1) to handle the case where no valid subarray exists (returns 0).class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
n = len(nums)
prefixSum = [0] * (n + 1)
for i in range(n):
prefixSum[i + 1] = prefixSum[i] + nums[i]
res = n + 1
for i in range(n):
l, r = i, n
while l < r:
mid = (l + r) // 2
curSum = prefixSum[mid + 1] - prefixSum[i]
if curSum >= target:
r = mid
else:
l = mid + 1
if l != n:
res = min(res, l - i + 1)
return res % (n + 1)The problem asks for sum greater than or equal to target, not exactly equal. A common bug is checking if (sum == target) instead of if (sum >= target). This causes the algorithm to miss valid subarrays where the sum exceeds the target, often returning 0 when a valid answer exists.
When no subarray sums to at least target, you must return 0. Initializing res to n + 1 or infinity and forgetting to check this at the end leads to returning invalid values. Always verify whether res was ever updated before returning it.
In the sliding window approach, some implementations shrink the window by moving the left pointer multiple times in a single iteration without rechecking the sum condition. The correct approach uses a while loop that continues shrinking only as long as sum >= target, updating the minimum length at each valid position.