209. Minimum Size Subarray Sum - Explanation
Description
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,000
Follow up: If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log(n)).
Topics
Prerequisites
Before attempting this problem, you should be comfortable with:
- Sliding Window Technique - Dynamically adjusting a window of elements by moving left and right pointers to find optimal subarrays
- Prefix Sum Arrays - Precomputing cumulative sums to enable O(1) range sum queries
- Binary Search - Efficiently finding target values or boundaries in sorted data in O(log n) time
1. Brute Force
Intuition
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.
Algorithm
- Initialize
resto infinity. - For each starting index
ifrom0ton-1:- Initialize
curSum = 0. - Expand
jfromiton-1, addingnums[j]tocurSum. - When
curSum >= target, updatereswithj - i + 1and break.
- Initialize
- Return
0ifresis still infinity, otherwise returnres.
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 resTime & Space Complexity
- Time complexity:
- Space complexity: extra space.
2. Sliding Window
Intuition
Since 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.
Algorithm
- Initialize
l = 0,total = 0, andres = infinity. - Iterate
rfrom0ton-1:- Add
nums[r]tototal. - While
total >= target:- Update
reswith the minimum ofresandr - l + 1. - Subtract
nums[l]fromtotaland incrementl.
- Update
- Add
- Return
0ifresis infinity, otherwise returnres.
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 resTime & Space Complexity
- Time complexity:
- Space complexity: extra space.
3. Prefix Sum + Binary Search
Intuition
We 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.
Algorithm
- Build a prefix sum array where
prefixSum[i]represents the sum of the firstielements. - For each starting index
i:- Binary search in range
[i, n]to find the smallestjwhereprefixSum[j+1] - prefixSum[i] >= target. - If found, update
reswithj - i + 1.
- Binary search in range
- Return
res % (n + 1)to handle the case where no valid subarray exists (returns0).
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)Time & Space Complexity
- Time complexity:
- Space complexity:
Common Pitfalls
Using Strict Equality Instead of Greater-Than-or-Equal
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.
Not Handling the No-Solution Case
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.
Shrinking the Window Too Aggressively
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.
Sign in to join the discussion