Hi👋SpeedAlgo • Deliberate Practice & Cognitive Ergonomics for Software Engineers

An interactive algorithm mastery and technical interview preparation platform published by Hi👋WebEnterprise. Built for senior and staff software engineers preparing for rigorous coding screens at top tech companies (FAANG/MAMAA).

13 Core Algorithmic Patterns & 225 Practice Problems

  • 1. Two Pointers (16 Paradigms, 43 Problems): Opposite ends, sorted pair sums, palindrome verification, trapping rain water, 3Sum, container with most water — includes the Sliding Window and Fast & Slow Pointers paradigms (contiguous subarray invariants, longest substrings, Floyd's cycle detection, linked list middle).
  • 2. Binary Search (9 Paradigms, 14 Problems): Monotonic predicate partitioning (feasible(x)), boundary search, rotated sorted arrays, square roots, minimum ship capacity, median of two sorted arrays, matrix median on value range.
  • 3. Bit Manipulation (5 Paradigms, 11 Problems): Counting set bits, XOR cancellation, bit reversal, bitmask pairing, maximum XOR with a bitwise trie.
  • 4. Math & Geometry (8 Paradigms, 14 Problems): Sieve of Eratosthenes, integer/roman conversions, modular arithmetic, geometric simulation.
  • 5. Tree/Graph Depth-First Search (15 Paradigms, 24 Problems): Path sums, lowest common ancestor, tree diameter, validating BSTs, tree DP (House Robber III, Binary Tree Cameras).
  • 6. Tree/Graph Breadth-First Search (5 Paradigms, 12 Problems): Level-order traversals, shortest path in unweighted graphs, zig-zag traversals, rotting oranges, word ladders.
  • 7. Graphs (12 Paradigms, 22 Problems): Topological sort, cycle detection, Dijkstra's algorithm, bipartite graph validation, network delay.
  • 8. Backtracking (6 Paradigms, 14 Problems): Subsets, permutations, combinations, constraint satisfaction, pruning, N-Queens, Sudoku solver.
  • 9. Dynamic Programming (13 Paradigms, 28 Problems): Memoization vs tabulation, 0/1 knapsack, unbounded knapsack, coin change, edit distance, longest common subsequence.
  • 10. Heap / Priority Queue (9 Paradigms, 11 Problems): Running medians, top-k elements, interval scheduling, IPO, k-way merges.
  • 11. Advanced Data Structures (7 Paradigms, 17 Problems): Trie (prefix tree), Union-Find (Disjoint Set Union), LRU Cache, LFU Cache, range-sum queries with updates.
  • 12. Stack (5 Paradigms, 9 Problems): Next greater element, largest rectangle in histogram, remove k digits, decode string, min stack.
  • 13. Intervals & Greedy (2 Paradigms, 6 Problems): Merge intervals, interval scheduling, meeting rooms by sweep line, jump game.

4-Stage Deliberate Practice Framework

  1. Stage 1 (Compare & Learn): Read the pattern's mental model, loop invariant and Big-O proof, compare the pattern's template with the problem's solution side by side, and use the step-by-step debugger. The solution can also be shown in C#, Java, TypeScript, C++, Go or Rust for almost every problem.
  2. Stage 2 (Active Recall): Rebuild the solution from memory in a code editor, with an invariant checklist and optional progressive hints, and check it against a judged test suite.
  3. Stage 3 (AI Interview Coach, coming soon): A mock-interview stage still in development; for now, students go straight from Stage 2 to Stage 4.
  4. Stage 4 (Solve on Your Own): Solve a new problem on your own against a 15-minute timer; your code is graded against a test suite. Python and TypeScript run in your browser and C# runs on our server (design problems grade in Python and TypeScript).

Equipped with a spaced-repetition review hub on a fixed 7-step schedule (1 day up to 90 days), a two-pane Studio workspace, and study notes.

Pricing, Access & Commercial Terms

  • Core Curriculum: 100% Free. No credit card required.
  • Coins: New accounts get 40 free coins once, the daily claim adds +20 coins once a day, and inviting a friend earns you +25 coins when they complete their first practice step. These are the only ways to earn coins.
  • AI Coach: Each AI coach question costs 1-5 coins, priced by the server according to its size.
  • BYOK (Bring Your Own Key): AI coaching is free with your own Google Gemini, OpenAI or OpenRouter API key (BYOK).
  • Extras: Coins also unlock extras for 24 hours: a Recall hint level (1 coin), a Solve solution reveal (2), a LeetCode problem card's solutions (1) and a pattern's extra canonical problems (1).
  • Payments & Refunds: Nothing on the site is sold for money: coins can only be earned, never bought. There are no subscriptions or charges, so there is nothing to refund.
  • Platform Operator: Hi👋WebEnterprise. Support & policies at hispeedalgo.com.
Skip to main content
Hi👋SpeedAlgo

Invariant-First Algorithmic Mastery

Arena
238Items
Theory Context•Two Pointers & Sliding Window
MediumLC 930

Binary Subarrays With Sum (LeetCode 930)

Target Frequency:GoogleAmazonMeta

You get an array nums in which every element is 0 or 1, and a whole number goal. A subarray is a run of one or more neighbouring elements of nums, taken without gaps. Count the subarrays whose elements add up to exactly goal, and return that number.

Subarrays are told apart by where they start and end: two runs at different positions both count, even if they hold the same values. When goal is 0, the subarrays made only of zeros are the ones that count.

Worked Examples

Example 1
Input:nums = [1,0,1,0,1], goal = 2
Output:4
1001120314111
Explanation: The runs with exactly two 1s are indices 0 to 2 (1,0,1), 0 to 3 (1,0,1,0), 1 to 4 (0,1,0,1) and 2 to 4 (1,0,1).
Example 2
Input:nums = [0,0,0,0,0], goal = 0
Output:15
0001020304
Explanation: Every run sums to 0, and five elements have 5 + 4 + 3 + 2 + 1 = 15 runs.

⚖️Formal Constraints & Bounds

  • 1 <= nums.length <= 3 * 104

  • nums[i] is either 0 or 1.

  • 0 <= goal <= nums.length

Deep-Dive & Conceptual Insights

Core Insight

"Exactly goal" is not a window you can slide, because zeros join and leave without changing the sum; "at most limit" is, so count at_most(goal) - at_most(goal - 1), where at_most(-1) is 0.

Real-World Scenario & Production Applications

Counting time windows with an exact number of events: a monitoring system that asks how many stretches of a minute-by-minute log contain exactly two failed deploys counts "at most two" and "at most one" with two sliding windows and subtracts, instead of checking every stretch.

Step-by-Step Execution Trace Table

nums = [1,0,0,1,0], goal = 0 (the trap preset): the answer is at_most(0) - at_most(-1).

StepCallrightnums[right]window after shrinkingleftcount += right - left + 1
1at_most(0)011 > 0: drop nums[0], window 01+ 0 -> 0
2at_most(0)1001+ 1 -> 1
3at_most(0)2001+ 2 -> 3
4at_most(0)311 > 0: drop nums[1], nums[2], nums[3], window 04+ 0 -> 3
5at_most(0)4004+ 1 -> 4
6at_most(-1)limit < 0: return 0 at once0
7answer4 - 0 = 4

Step 3 adds 2: the zero runs [0] (index 2) and [0,0] (indices 1 to 2) both end at right = 2. Without the guard in step 6, at_most(-1) would look for a window with a negative sum, move left past right, and read past the end of nums.

Worked on Paper

The Math, Step by Step

1. The numbers the code counts

Call E(g)E(g)E(g) the number of subarrays whose total is exactly ggg. This is the answer the problem asks for, with ggg = goal. Call M(g)M(g)M(g) the number of subarrays whose total is at most ggg, that is, less than or equal to ggg. The code computes MMM with the helper at_most(limit), and never computes EEE directly.

2. The formula: exactly equals at most minus at most one less

Every element of nums is 0 or 1, so every subarray total is a whole number. A whole number that is at most ggg is either equal to ggg or at most g−1g - 1g−1. These two groups do not overlap. So

M(g)=E(g)+M(g−1)⟹E(g)=M(g)−M(g−1)M(g) = E(g) + M(g - 1) \quad\Longrightarrow\quad E(g) = M(g) - M(g - 1)M(g)=E(g)+M(g−1)⟹E(g)=M(g)−M(g−1)

The code returns at_most(goal) - at_most(goal - 1), which is this formula. The step "at most g−1g - 1g−1" is right only because the totals are whole numbers. With real-number totals, a total such as g−0.5g - 0.5g−0.5 would be in neither group.

3. Why one window counts all subarrays with total at most limit

at_most(limit) moves right from left to right. For each right, it moves left forward until the total of nums[left..right] is at most limit. Then it adds right - left + 1 to count.

This count is correct because no value is negative. Start with the fitting window nums[left..right]. Every subarray that ends at right and starts at an index from left to right is the window or a part of it. It holds some or all of the window's elements, so its total is less than or equal to the window's total. So all right - left + 1 of them fit. A subarray that starts before left does not fit. The window moved past that start only because the total was greater than limit.

left never moves back. So left and right each move at most nnn times, and one call of at_most takes O(n)O(n)O(n) time.

4. The case goal = 0

When goal is 0, the code asks for at_most(-1). No subarray has a total of at most −1-1−1, because no value is negative. So M(−1)=0M(-1) = 0M(−1)=0, and the helper returns 0 at once with if limit < 0.

The early return also keeps the loop safe. Without it, the condition window > -1 stays true even after the window is empty. Then left moves past right and past the end of nums.

5. Example 1 by hand

nums = [1,0,1,0,1], goal = 2. First the call at_most(2):

rightnums[right]window after shrinkingleftAdded: right - left + 1count
011011
101023
212036
3020410
4121414

At right = 4 the total becomes 333, which is greater than 222. So the window drops nums[0] = 1 and left becomes 111. Then the call at_most(1):

rightnums[right]window after shrinkingleftAdded: right - left + 1count
011011
101023
211125
301138
4113210

So M(2)=14M(2) = 14M(2)=14 and M(1)=10M(1) = 10M(1)=10. The code returns 14−10=414 - 10 = 414−10=4, the expected output. The four subarrays are the ones with exactly two 1s: indices 0 to 2, 0 to 3, 1 to 4 and 2 to 4.

6. Example 2 by hand

nums = [0,0,0,0,0], goal = 0. In at_most(0) the window total stays 000, so left stays at 000. The added amounts are 1,2,3,4,51, 2, 3, 4, 51,2,3,4,5, and M(0)=15M(0) = 15M(0)=15. The call at_most(-1) returns 000 at once. The code returns 15−0=1515 - 0 = 1515−0=15, the expected output.

7. From the formulas to the code
FormulaIn numSubarraysWithSum
E(g)=M(g)−M(g−1)E(g) = M(g) - M(g - 1)E(g)=M(g)−M(g−1)return at_most(goal) - at_most(goal - 1)
M(−1)=0M(-1) = 0M(−1)=0if limit < 0: followed by return 0
total of nums[left..right]window
shrink until the total is at most limitwhile window > limit:
subarrays ending at right that fitcount += right - left + 1

The function makes two calls of at_most, and each takes O(n)O(n)O(n) time. It keeps only a few integers, so it uses O(1)O(1)O(1) extra space.

Code Shape
Archetype Code Shape
Python
1"Exactly `goal`" can't be slid, but "at most `limit`" can: count both `at_most(goal)` and `at_most(goal - 1)` and subtract.
2Keep this true: inside `at_most(limit)`, `nums[left..right]` is the longest window ending at `right` whose sum is at most `limit`.
3The shape: a helper `at_most(limit)` with one `for right` loop that grows the window, an inner loop that shrinks it from the left, and one addition to `count` per `right`; the answer combines two calls of the helper.
4The trap: `goal = 0` asks for `at_most(-1)`. Return 0 for a negative `limit`, or the shrink loop walks `left` off the end of `nums`.

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition

Counting subarrays whose sum is exactly goal sounds like a sliding window, but it isn't one: in [0,0,1,0,0] with goal = 1, the 1 fits in nine different runs, and the zeros on both sides can join or leave without changing the sum. No single left edge describes them all. Counting subarrays whose sum is at most limit is a clean window: if nums[left..right] fits, every shorter window ending at right fits too, so for each right there is one smallest left, and right - left + 1 subarrays end there. The At-Most Trick counts two of those and subtracts: at_most(goal) - at_most(goal - 1) leaves exactly the sums equal to goal.

🧺 The Analogy: Shelves With a Weight Limit

A shelf holds at most 2 kilos. Knowing how many runs of books fit on a 2-kilo shelf, and how many fit on a 1-kilo shelf, tells you how many runs weigh more than 1 kilo but at most 2: subtract the two numbers. Counting runs that weigh exactly some amount directly is awkward, because weightless bookmarks can be added or removed at either end of a run.

🔑 Why It Works

Each subarray with sum at most goal has sum exactly goal or at most goal - 1, so the subtraction is exact. When goal is 0, the second call asks for a negative limit: no window can ever fit, so without the early return 0 the while loop would push left past right and off the end of nums.

  • A negative limit: goal = 0 asks for at_most(-1). if limit < 0: return 0, or the while window > limit loop walks left past right and off the end of nums.

  • Counting one subarray per end: add right - left + 1, not 1. Every start from left to right gives a subarray whose sum is at most limit.

  • Shrinking only once: use while window > limit, not if. After a 1 joins, nums[left] may be a 0, and one step leaves the sum over limit.

  • One window for "exactly": counting a window when its sum equals goal misses the runs that start at a zero the window already dropped; in [1,0,1,0,1] with goal = 2 it finds fewer than 4.

  • Keys left at zero, as in Subarrays with K Different Integers (LC 992): with different values as the amount, del a value whose count drops to 0, or len(copies) stays too high.

  • Not the only correct shape: a single window with two left pointers (one marking where it first reaches exactly k different values, one where it first exceeds k) also solves this in one pass; the at-most/at-most difference is preferred here because it reuses one window function instead of tracking two left edges.

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

"Count the subarrays whose elements add up to exactly goal" with "every element is 0 or 1": an exact count over subarrays, where adding an element never lowers the sum, so the signal is the At-Most Trick: exactly(goal) = at_most(goal) - at_most(goal - 1). "When goal is 0" warns that at_most(-1) will be asked for.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Inside at_most(limit), after each right, nums[left..right] is the longest window ending at right whose sum is at most limit, so count += right - left + 1 adds every such subarray once; the answer is at_most(goal) - at_most(goal - 1).

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • count += right - left + 1: on LeetCode's [0,0,0,0,0] with goal = 0 the answer is 15, and count += 1 gives 5 (gotcha 2).

  • while window > limit: on LeetCode's [1,0,1,0,1] with goal = 2 a single if gives 3 instead of 4 (gotcha 3).

The 60-Second Interview Pitch

Say this out loud before you type a single line

I'd use the At-Most Trick. Counting subarrays whose sum is exactly goal with one window doesn't work, because zeros can join or leave without changing the sum, so there's no single left edge to track. Counting subarrays whose sum is at most some limit does work: I grow the window to the right, shrink it from the left while the sum is over the limit, and add right minus left plus one for every right end, since every start inside the window fits. Then exactly goal is at most goal minus at most goal minus one, because each subarray lands in exactly one of those two groups. The trap is goal equal to zero: that asks for at most minus one, which has to be zero, so I return early for a negative limit instead of letting the window run off the end. Two passes, O(N) time and O(1) space.

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N)

at_most(limit) runs for right in range(len(nums)): N steps, each with one addition and one count +=. The inner while window > limit moves left one place per step, and left only moves forward and never passes N, so across the whole pass the while body runs at most N times in all. One pass is O(N). numSubarraysWithSum makes two passes, at_most(goal) and at_most(goal - 1) (the second returns at once when goal is 0): O(2N) = O(N).

SPACE COMPLEXITY

O(1)

Each pass keeps limit, left, window, count and right: O(1) extra space. The two calls run one after the other, so the stack never holds more than one at_most frame. The answer is one integer.

Formal Recurrence Relation

T(N) = 2 passes x (N moves of right + at most N moves of left) = O(N)

Derivation Progression

Grow

N

for right in range(len(nums)) adds each element to window once per pass.

Shrink

at most N

Each run of the while body moves left forward by one; left never moves back and never passes N, so all shrinks in a pass add up to at most N.

Count

N

count += right - left + 1 is one addition per right, however many subarrays it counts.

Two passes

O(N)

at_most(goal) and at_most(goal - 1) each cost O(N); their difference is one subtraction.

Variable Definitions

NNN

Number of elements, len(nums) (at most 3 * 10^4)

Memory Architecture & Bounds

🟣 Call Stack

O(1): one at_most frame at a time

🔵 Auxiliary Heap

O(1): limit, left, window, count, right

🟢 Output Space

O(1): one integer

Boundary Best / Worst Cases

Best Case

O(N)O(N)O(N): goal = 0, so the second pass returns at once, but the first still reads every element

Average Case

O(N)O(N)O(N)

Worst Case

O(N)O(N)O(N): two full passes, with left crossing the whole array in each

Pointer Invariant Transition Progression

Pointer Invariant Transition Progression
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

At scale the signal is "count the windows with exactly K events" over a log or a stream: any amount that only grows as items join, asked for an exact value, splits into two at-most counts that each slide.

CONSTRAINTS & BOUNDS

Up to 3×1043 \times 10^43×104 elements. Checking every subarray is about 4.5×1084.5 \times 10^84.5×108 additions; two sliding-window passes are about 1.2×1051.2 \times 10^51.2×105 pointer moves. The answer can reach N(N+1)/2≈4.5×108N(N + 1) / 2 \approx 4.5 \times 10^8N(N+1)/2≈4.5×108, which still fits a 32-bit integer, but at 10510^5105 elements it would not.

FAANG PRODUCTION TRAPS & EDGE CASES

On a stream, the two counts can run side by side as two windows over the same input, so the log is read once; the same subtraction answers "exactly K events in a window" as long as events only add, never cancel. Counts over long streams outgrow 32 bits quickly: keep them in 64-bit integers.

Core Algorithmic State Invariants

  1. The Same Difference Counts Any Range

Exactly goal is the range goal..goal: a count between lo and hi is at_most(hi) - at_most(lo - 1). Number of Subarrays with Bounded Maximum (LC 795) uses the same difference on the largest value instead of the sum.

Theory Context•Two Pointers & Sliding Window
MediumLC 930

Binary Subarrays With Sum (LeetCode 930)

Target Frequency:GoogleAmazonMeta

You get an array nums in which every element is 0 or 1, and a whole number goal. A subarray is a run of one or more neighbouring elements of nums, taken without gaps. Count the subarrays whose elements add up to exactly goal, and return that number.

Subarrays are told apart by where they start and end: two runs at different positions both count, even if they hold the same values. When goal is 0, the subarrays made only of zeros are the ones that count.

Worked Examples

Example 1
Input:nums = [1,0,1,0,1], goal = 2
Output:4
1001120314111
Explanation: The runs with exactly two 1s are indices 0 to 2 (1,0,1), 0 to 3 (1,0,1,0), 1 to 4 (0,1,0,1) and 2 to 4 (1,0,1).
Example 2
Input:nums = [0,0,0,0,0], goal = 0
Output:15
0001020304
Explanation: Every run sums to 0, and five elements have 5 + 4 + 3 + 2 + 1 = 15 runs.

⚖️Formal Constraints & Bounds

  • 1 <= nums.length <= 3 * 104

  • nums[i] is either 0 or 1.

  • 0 <= goal <= nums.length

Deep-Dive & Conceptual Insights

Core Insight

"Exactly goal" is not a window you can slide, because zeros join and leave without changing the sum; "at most limit" is, so count at_most(goal) - at_most(goal - 1), where at_most(-1) is 0.

Real-World Scenario & Production Applications

Counting time windows with an exact number of events: a monitoring system that asks how many stretches of a minute-by-minute log contain exactly two failed deploys counts "at most two" and "at most one" with two sliding windows and subtracts, instead of checking every stretch.

Step-by-Step Execution Trace Table

nums = [1,0,0,1,0], goal = 0 (the trap preset): the answer is at_most(0) - at_most(-1).

StepCallrightnums[right]window after shrinkingleftcount += right - left + 1
1at_most(0)011 > 0: drop nums[0], window 01+ 0 -> 0
2at_most(0)1001+ 1 -> 1
3at_most(0)2001+ 2 -> 3
4at_most(0)311 > 0: drop nums[1], nums[2], nums[3], window 04+ 0 -> 3
5at_most(0)4004+ 1 -> 4
6at_most(-1)limit < 0: return 0 at once0
7answer4 - 0 = 4

Step 3 adds 2: the zero runs [0] (index 2) and [0,0] (indices 1 to 2) both end at right = 2. Without the guard in step 6, at_most(-1) would look for a window with a negative sum, move left past right, and read past the end of nums.

Worked on Paper

The Math, Step by Step

1. The numbers the code counts

Call E(g)E(g)E(g) the number of subarrays whose total is exactly ggg. This is the answer the problem asks for, with ggg = goal. Call M(g)M(g)M(g) the number of subarrays whose total is at most ggg, that is, less than or equal to ggg. The code computes MMM with the helper at_most(limit), and never computes EEE directly.

2. The formula: exactly equals at most minus at most one less

Every element of nums is 0 or 1, so every subarray total is a whole number. A whole number that is at most ggg is either equal to ggg or at most g−1g - 1g−1. These two groups do not overlap. So

M(g)=E(g)+M(g−1)⟹E(g)=M(g)−M(g−1)M(g) = E(g) + M(g - 1) \quad\Longrightarrow\quad E(g) = M(g) - M(g - 1)M(g)=E(g)+M(g−1)⟹E(g)=M(g)−M(g−1)

The code returns at_most(goal) - at_most(goal - 1), which is this formula. The step "at most g−1g - 1g−1" is right only because the totals are whole numbers. With real-number totals, a total such as g−0.5g - 0.5g−0.5 would be in neither group.

3. Why one window counts all subarrays with total at most limit

at_most(limit) moves right from left to right. For each right, it moves left forward until the total of nums[left..right] is at most limit. Then it adds right - left + 1 to count.

This count is correct because no value is negative. Start with the fitting window nums[left..right]. Every subarray that ends at right and starts at an index from left to right is the window or a part of it. It holds some or all of the window's elements, so its total is less than or equal to the window's total. So all right - left + 1 of them fit. A subarray that starts before left does not fit. The window moved past that start only because the total was greater than limit.

left never moves back. So left and right each move at most nnn times, and one call of at_most takes O(n)O(n)O(n) time.

4. The case goal = 0

When goal is 0, the code asks for at_most(-1). No subarray has a total of at most −1-1−1, because no value is negative. So M(−1)=0M(-1) = 0M(−1)=0, and the helper returns 0 at once with if limit < 0.

The early return also keeps the loop safe. Without it, the condition window > -1 stays true even after the window is empty. Then left moves past right and past the end of nums.

5. Example 1 by hand

nums = [1,0,1,0,1], goal = 2. First the call at_most(2):

rightnums[right]window after shrinkingleftAdded: right - left + 1count
011011
101023
212036
3020410
4121414

At right = 4 the total becomes 333, which is greater than 222. So the window drops nums[0] = 1 and left becomes 111. Then the call at_most(1):

rightnums[right]window after shrinkingleftAdded: right - left + 1count
011011
101023
211125
301138
4113210

So M(2)=14M(2) = 14M(2)=14 and M(1)=10M(1) = 10M(1)=10. The code returns 14−10=414 - 10 = 414−10=4, the expected output. The four subarrays are the ones with exactly two 1s: indices 0 to 2, 0 to 3, 1 to 4 and 2 to 4.

6. Example 2 by hand

nums = [0,0,0,0,0], goal = 0. In at_most(0) the window total stays 000, so left stays at 000. The added amounts are 1,2,3,4,51, 2, 3, 4, 51,2,3,4,5, and M(0)=15M(0) = 15M(0)=15. The call at_most(-1) returns 000 at once. The code returns 15−0=1515 - 0 = 1515−0=15, the expected output.

7. From the formulas to the code
FormulaIn numSubarraysWithSum
E(g)=M(g)−M(g−1)E(g) = M(g) - M(g - 1)E(g)=M(g)−M(g−1)return at_most(goal) - at_most(goal - 1)
M(−1)=0M(-1) = 0M(−1)=0if limit < 0: followed by return 0
total of nums[left..right]window
shrink until the total is at most limitwhile window > limit:
subarrays ending at right that fitcount += right - left + 1

The function makes two calls of at_most, and each takes O(n)O(n)O(n) time. It keeps only a few integers, so it uses O(1)O(1)O(1) extra space.

Code Shape
Archetype Code Shape
Python
1"Exactly `goal`" can't be slid, but "at most `limit`" can: count both `at_most(goal)` and `at_most(goal - 1)` and subtract.
2Keep this true: inside `at_most(limit)`, `nums[left..right]` is the longest window ending at `right` whose sum is at most `limit`.
3The shape: a helper `at_most(limit)` with one `for right` loop that grows the window, an inner loop that shrinks it from the left, and one addition to `count` per `right`; the answer combines two calls of the helper.
4The trap: `goal = 0` asks for `at_most(-1)`. Return 0 for a negative `limit`, or the shrink loop walks `left` off the end of `nums`.

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition

Counting subarrays whose sum is exactly goal sounds like a sliding window, but it isn't one: in [0,0,1,0,0] with goal = 1, the 1 fits in nine different runs, and the zeros on both sides can join or leave without changing the sum. No single left edge describes them all. Counting subarrays whose sum is at most limit is a clean window: if nums[left..right] fits, every shorter window ending at right fits too, so for each right there is one smallest left, and right - left + 1 subarrays end there. The At-Most Trick counts two of those and subtracts: at_most(goal) - at_most(goal - 1) leaves exactly the sums equal to goal.

🧺 The Analogy: Shelves With a Weight Limit

A shelf holds at most 2 kilos. Knowing how many runs of books fit on a 2-kilo shelf, and how many fit on a 1-kilo shelf, tells you how many runs weigh more than 1 kilo but at most 2: subtract the two numbers. Counting runs that weigh exactly some amount directly is awkward, because weightless bookmarks can be added or removed at either end of a run.

🔑 Why It Works

Each subarray with sum at most goal has sum exactly goal or at most goal - 1, so the subtraction is exact. When goal is 0, the second call asks for a negative limit: no window can ever fit, so without the early return 0 the while loop would push left past right and off the end of nums.

  • A negative limit: goal = 0 asks for at_most(-1). if limit < 0: return 0, or the while window > limit loop walks left past right and off the end of nums.

  • Counting one subarray per end: add right - left + 1, not 1. Every start from left to right gives a subarray whose sum is at most limit.

  • Shrinking only once: use while window > limit, not if. After a 1 joins, nums[left] may be a 0, and one step leaves the sum over limit.

  • One window for "exactly": counting a window when its sum equals goal misses the runs that start at a zero the window already dropped; in [1,0,1,0,1] with goal = 2 it finds fewer than 4.

  • Keys left at zero, as in Subarrays with K Different Integers (LC 992): with different values as the amount, del a value whose count drops to 0, or len(copies) stays too high.

  • Not the only correct shape: a single window with two left pointers (one marking where it first reaches exactly k different values, one where it first exceeds k) also solves this in one pass; the at-most/at-most difference is preferred here because it reuses one window function instead of tracking two left edges.

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

"Count the subarrays whose elements add up to exactly goal" with "every element is 0 or 1": an exact count over subarrays, where adding an element never lowers the sum, so the signal is the At-Most Trick: exactly(goal) = at_most(goal) - at_most(goal - 1). "When goal is 0" warns that at_most(-1) will be asked for.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Inside at_most(limit), after each right, nums[left..right] is the longest window ending at right whose sum is at most limit, so count += right - left + 1 adds every such subarray once; the answer is at_most(goal) - at_most(goal - 1).

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • count += right - left + 1: on LeetCode's [0,0,0,0,0] with goal = 0 the answer is 15, and count += 1 gives 5 (gotcha 2).

  • while window > limit: on LeetCode's [1,0,1,0,1] with goal = 2 a single if gives 3 instead of 4 (gotcha 3).

The 60-Second Interview Pitch

Say this out loud before you type a single line

I'd use the At-Most Trick. Counting subarrays whose sum is exactly goal with one window doesn't work, because zeros can join or leave without changing the sum, so there's no single left edge to track. Counting subarrays whose sum is at most some limit does work: I grow the window to the right, shrink it from the left while the sum is over the limit, and add right minus left plus one for every right end, since every start inside the window fits. Then exactly goal is at most goal minus at most goal minus one, because each subarray lands in exactly one of those two groups. The trap is goal equal to zero: that asks for at most minus one, which has to be zero, so I return early for a negative limit instead of letting the window run off the end. Two passes, O(N) time and O(1) space.

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N)

at_most(limit) runs for right in range(len(nums)): N steps, each with one addition and one count +=. The inner while window > limit moves left one place per step, and left only moves forward and never passes N, so across the whole pass the while body runs at most N times in all. One pass is O(N). numSubarraysWithSum makes two passes, at_most(goal) and at_most(goal - 1) (the second returns at once when goal is 0): O(2N) = O(N).

SPACE COMPLEXITY

O(1)

Each pass keeps limit, left, window, count and right: O(1) extra space. The two calls run one after the other, so the stack never holds more than one at_most frame. The answer is one integer.

Formal Recurrence Relation

T(N) = 2 passes x (N moves of right + at most N moves of left) = O(N)

Derivation Progression

Grow

N

for right in range(len(nums)) adds each element to window once per pass.

Shrink

at most N

Each run of the while body moves left forward by one; left never moves back and never passes N, so all shrinks in a pass add up to at most N.

Count

N

count += right - left + 1 is one addition per right, however many subarrays it counts.

Two passes

O(N)

at_most(goal) and at_most(goal - 1) each cost O(N); their difference is one subtraction.

Variable Definitions

NNN

Number of elements, len(nums) (at most 3 * 10^4)

Memory Architecture & Bounds

🟣 Call Stack

O(1): one at_most frame at a time

🔵 Auxiliary Heap

O(1): limit, left, window, count, right

🟢 Output Space

O(1): one integer

Boundary Best / Worst Cases

Best Case

O(N)O(N)O(N): goal = 0, so the second pass returns at once, but the first still reads every element

Average Case

O(N)O(N)O(N)

Worst Case

O(N)O(N)O(N): two full passes, with left crossing the whole array in each

Pointer Invariant Transition Progression

Pointer Invariant Transition Progression
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

At scale the signal is "count the windows with exactly K events" over a log or a stream: any amount that only grows as items join, asked for an exact value, splits into two at-most counts that each slide.

CONSTRAINTS & BOUNDS

Up to 3×1043 \times 10^43×104 elements. Checking every subarray is about 4.5×1084.5 \times 10^84.5×108 additions; two sliding-window passes are about 1.2×1051.2 \times 10^51.2×105 pointer moves. The answer can reach N(N+1)/2≈4.5×108N(N + 1) / 2 \approx 4.5 \times 10^8N(N+1)/2≈4.5×108, which still fits a 32-bit integer, but at 10510^5105 elements it would not.

FAANG PRODUCTION TRAPS & EDGE CASES

On a stream, the two counts can run side by side as two windows over the same input, so the log is read once; the same subtraction answers "exactly K events in a window" as long as events only add, never cancel. Counts over long streams outgrow 32 bits quickly: keep them in 64-bit integers.

Core Algorithmic State Invariants

  1. The Same Difference Counts Any Range

Exactly goal is the range goal..goal: a count between lo and hi is at_most(hi) - at_most(lo - 1). Number of Subarrays with Bounded Maximum (LC 795) uses the same difference on the largest value instead of the sum.

© 2026 Hi👋WebEnterprise. All rights reserved.
Sitemap•llms.txt•