Minimum Size Subarray Sum (LC 209)
On this page
Pattern: Sliding Window (variable size)
Difficulty: Medium
Key Concept: Expand the window until the sum is large enough, then shrink from the left to minimize length while the sum stays valid.
Problem Statement
You are given an array nums of positive integers and a positive integer target.
Return the minimum length of a contiguous subarray whose sum is greater than or equal to target. If no such subarray exists, return 0.
Input
nums: int[] — all elements are positivetarget: int — positive
Output
- int — minimum length of a subarray with sum ≥
target, or0if impossible
Constraints (typical)
1 <= nums.length <= 10^51 <= nums[i] <= 10^41 <= target <= 10^9
1. Algorithm & Pseudocode
Brute force (check every subarray)
minLen = infinity
for start from 0 to n-1:
sum = 0
for end from start to n-1:
sum += nums[end]
if sum >= target:
minLen = min(minLen, end - start + 1)
break // extending end only increases length for this start
return minLen if minLen != infinity else 0
Optimal (variable-size sliding window)
Because all numbers are positive, when you extend right the sum only grows, and when you move left forward the sum only shrinks. That monotonicity lets you use one pass.
left = 0
sum = 0
minLen = infinity
for right from 0 to n-1:
sum += nums[right]
while sum >= target:
minLen = min(minLen, right - left + 1)
sum -= nums[left]
left += 1
return minLen if minLen != infinity else 0
2. Step-by-Step Analysis (Beginner-Friendly)
-
Why brute force is slow
Every pair(start, end)is a candidate. There are on the order ofn^2subarrays, and summing each naively repeats work. -
Why positivity matters
If you could have negative numbers, shrinking the window might increase the sum, so a simple “expand then shrink” window does not capture all optimal subarrays. Here, positivity guarantees that oncesum >= target, movingleftright only decreases sum—so you can safely search for the shortest window ending atright. -
What
leftrepresents
leftis the start of the current window.rightis the end. The window is alwaysnums[left..right]. -
Why the inner
while sum >= target
As long as the window still satisfiessum >= target, you can try to shorten it by movingleftone step right. Each time you do, you might get a smaller lengthright - left + 1. Stop whensum < target(window too small) orleftpassesright. -
Why we do not reset
leftto 0
After we shrink, the nextrightmight still allow a valid window that starts at the currentleft. Starting over from 0 would redo work and break the linear-time idea. -
Integer.MAX_VALUEfor “no answer yet”
We need a sentinel larger than any real answer soMath.minworks. If we finish andminLenis still that sentinel, return0.
3. The Dry Run
Sample: target = 7, nums = [2, 3, 1, 2, 4, 3]
Optimal sliding window (indices 0-based).
| Step | right |
nums[right] |
sum (after add) |
sum >= 7? |
Action in while |
left after |
minLen |
|---|---|---|---|---|---|---|---|
| init | — | — | 0 | no | — | 0 | ∞ |
| 1 | 0 | 2 | 2 | no | — | 0 | ∞ |
| 2 | 1 | 3 | 5 | no | — | 0 | ∞ |
| 3 | 2 | 1 | 6 | no | — | 0 | ∞ |
| 4 | 3 | 2 | 8 | yes | shrink: sum-=2 → 6 |
1 | 4 |
| 4b | — | — | 6 | no | exit while | 1 | 4 |
| 5 | 4 | 4 | 10 | yes | shrink: sum-=3 → 7 |
2 | 4 |
| 5b | — | — | 7 | yes | shrink: sum-=1 → 6 |
3 | 3 |
| 5c | — | — | 6 | no | exit while | 3 | 3 |
| 6 | 5 | 3 | 9 | yes | shrink: sum-=2 → 7 |
4 | 3 |
| 6b | — | — | 7 | yes | shrink: sum-=4 → 3 |
5 | 2 |
| 6c | — | — | 3 | no | exit while | 5 | 2 |
Result: minLen = 2 (subarray [4, 3] at indices 4–5, sum 7).
4. Java Solution
Brute Force
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int n = nums.length;
int minLen = Integer.MAX_VALUE;
for (int start = 0; start < n; start++) {
int sum = 0;
for (int end = start; end < n; end++) {
sum += nums[end];
if (sum >= target) {
minLen = Math.min(minLen, end - start + 1);
break;
}
}
}
return minLen == Integer.MAX_VALUE ? 0 : minLen;
}
}
Time: O(n²) in the worst case (nested loops).
Space: O(1).
Optimal
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left = 0;
int sum = 0;
int minLen = Integer.MAX_VALUE;
for (int right = 0; right < nums.length; right++) {
sum += nums[right];
while (sum >= target) {
minLen = Math.min(minLen, right - left + 1);
sum -= nums[left];
left++;
}
}
return minLen == Integer.MAX_VALUE ? 0 : minLen;
}
}
Time: O(n) — each index moves at most a constant number of times as left and right march forward.
Space: O(1).
5. The “Java vs. Others” Edge
Integer.MAX_VALUE: Java uses this as a practical “infinity” for minimum-length problems. In C++ you often useINT_MAXfrom<climits>. In Python,float('inf')is common (or a very large int).Math.min: Works withint; no risk of forgetting a namespace (C++std::minneeds headers and care with macros).- No unsigned index types: Loop indices are
int; for huge arrays in competitive settings, be aware of overflow only if you multiply lengths—here lengths stay inintrange per problem constraints. - Contrast with Python: Python’s arbitrary-precision ints avoid overflow on
sum, but Javaintis fine for given LeetCode constraints; uselongforsumif constraints allowed huge partial sums.
6. Complexity Summary
| Approach | Time | Space | Notes |
|---|---|---|---|
| Brute Force | O(n²) | O(1) | Tries each start; inner loop can break early after first valid end. |
| Optimal | O(n) | O(1) | Relies on all nums[i] > 0; two pointers, each moves forward only. |