Binary Subarrays With Sum
Counting subarrays with sum ≤ k is easy with a sliding window. So count sum ≤ goal, count sum ≤ goal − 1, and subtract. What is left is exactly the subarrays with sum goal.
In each pass, the window is valid when sum ≤ k. Adding elements can only make the sum bigger and removing them can only make it smaller, so this rule is safe to shrink on — unlike "sum = goal".
Problem
You are given an array nums that contains only 0s and 1s, and a number goal.
Count how many contiguous, non-empty subarrays add up to exactly goal.
A binary array nums (every value is 0 or 1) and an integer goal.
The number of non-empty subarrays whose sum equals goal.
The subarrays with sum 2 are [1,0,1] (indices 0..2), [1,0,1,0] (0..3), [0,1,0,1] (1..4) and [1,0,1] (2..4).
Every subarray is all zeros, so every one of the 5·6/2 = 15 subarrays has sum 0.
- • 1 ≤ nums.length ≤ 3 · 10^4
- • nums[i] is either 0 or 1
- • 0 ≤ goal ≤ nums.length
First, think yourself
Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.
- 1.
If I fix where a subarray ends, how many different starts could give the same sum?
- 2.
What does a 0 do to the sum when it enters or leaves the window?
- 3.
If my window has sum exactly
goal, should I shrink it or not? Can I tell? - 4.
Is "sum ≤ goal" easier to keep true with a window than "sum = goal"? Why?
- 5.
If I can count subarrays with sum ≤ x for any x, how do I get the ones with sum = x?
Brute force approach
Better approach
Optimized approach
Why does this algorithm work?
Dry run
All approaches compared
| Approach | Idea | Time | Space |
|---|---|---|---|
| Brute Force | Fix each start, grow the end, count when the sum hits goal | O(N²) | O(1) |
| Better | Count earlier prefix sums equal to (current prefix − goal) | O(N) | O(N) |
| Optimal | Two at-most windows; their difference is the exactly-goal count | O(N) | O(1) |
Why does this belong to this pattern?
- “contiguous subarrays”We are counting ranges [l..r] → window or prefix sum.
- “count how many”The answer is a count, so each right end adds a number of starts (right − left + 1), not a max.
- “sum equals exactly goal”"Exactly" breaks the shrink rule → split into two "at most" counts.
- “only 0s and 1s”No negatives, so "sum ≤ k" behaves well for a window. With negatives, only the prefix-sum version works.
This is the anchor of the Exactly K sub-pattern. You already know how to count "at most" subarrays (the At Most K sub-pattern). Here the rule is "sum ≤ k" on a 0/1 array, and the new move is the subtraction. The same problem is also a classic Prefix Sum + hash map problem (Subarray Sum Equals K). Know both: prefix sums work even with negative numbers; the two-window trick only works when values are non-negative, but uses O(1) space.
Don't make this mistake
For one right end, several starts can give sum goal (they differ only by zeros on the left). This code counts just one of them. On [0,0,1], goal 1, it returns 1 instead of 3.
When goal = 0 you call atMost(−1). Without the guard, while (sum > -1) is always true (a sum is never negative), so left runs past right and then off the end of the array. No subarray has a negative sum, so the answer is 0.
We count subarrays, not windows. All starts from left to right give a valid subarray ending at right.
This is a pattern-confusion trap. On a general integer array (like Subarray Sum Equals K), "sum ≤ k" is no longer monotonic — adding a negative number makes the sum smaller. There you must use the prefix sum + hash map approach. The two-window trick works here only because values are 0 or 1.
Want to implement this?
Write it yourself on LeetCode, then come back and compare your code with the solutions above.
Open coding workspaceHow this concept connects to System Design & C++ Systems
Top engineering interviews test whether you understand how algorithms like Sliding Window translate into production architectures and low-level memory mechanics.