skip to content

Why does a sliding window fail to find a stretch summing to a target when values can be negative?

level: seniorimportance: should knowfreq 52%

answer

  1. The window is a greedy argument, not an identity
  2. What must growing the window guarantee
  3. Can a longer stretch total less
  4. Once the left pointer moves, can it return
  5. One approach costs state, the other assumptions

basics

~20 s

A two-pointer window relies on the sum being monotone in the window's extent: growing never lowers it, shrinking never raises it. Negative values break that, so a window discarded as too large may be exactly the one you needed. Prefix totals plus a map of seen totals assume no monotonicity at all.

solid answer

~50 s

The expand-and-shrink window is a greedy search, and its correctness rests on one assumption: adding an element cannot decrease the running sum, so once the window overshoots the target, moving the left edge right is guaranteed to be the only useful move and the discarded left positions never need revisiting. Introduce a single negative value and that ordering collapses — a longer window can total less than a shorter one — so the pointer that was advanced past a position may have to come back, and the algorithm's whole pruning argument is void. The prefix-total-plus-map approach is not greedy: it is an algebraic identity, `sum(l..r) = P[r+1] - P[l]`, so it is indifferent to sign. The price is O(n) memory and hashing overhead versus the window's O(1) state, which is exactly the trade you should name when choosing.

go deeper

for a junior

Know that a two-pointer window over a contiguous range assumes adding an element never lowers the running sum, and that this is only true when values cannot be negative.

for a middle

Explain both halves of the window's correctness argument — monotone growth and safe discard of left positions — and show which half each negative value destroys. Contrast with the sign-agnostic prefix-total identity.

for a senior

Make the choice explicit and defend it with costs: O(1) state and streaming friendliness against O(n) memory and hashing overhead. Ask whether non-negativity is a domain guarantee or an accident of the sample data.

for a principal

Own the risk framing: a window used on data that later admits negative values fails silently with wrong answers rather than errors. Decide whether to encode the invariant, validate it at the boundary, or pay for the sign-agnostic approach up front.

## Two patterns, one problem shape Both patterns answer questions about contiguous stretches in one pass, and interviewers deliberately blur them. The decision usually turns on a single property of the data: whether the values are guaranteed non-negative. ## What the window actually assumes The expand-and-shrink window maintains a current sum for the range between two pointers, growing the right edge and, when the sum overshoots, advancing the left edge. Its correctness argument is greedy and has two halves: 1. **Monotone growth.** Extending the right edge never decreases the window sum, so if a window is already too large the only way toward the target is to shrink. 2. **Safe discard.** Once the left pointer passes a position, no future answer needs it, so each pointer advances at most n times, giving linear time with O(1) state. Sign is what underwrites both. With all values non-negative, sum is a monotone function of the window's extent. With a single negative value present, a longer window can total LESS than a shorter one, so an overshooting window may be fixed by growing rather than shrinking, and a left position discarded as unusable can be needed again. Neither half survives, and the pattern does not merely get slower — it returns wrong answers, which is worse. Zeros are a milder case: they keep the sum non-decreasing but not strictly increasing, so feasibility survives while COUNTING variants get delicate — a run of zeros creates many windows with identical sums, and naive two-pointer counting either double-counts or misses them. ## What the prefix map assumes Nothing about sign. It rests on an identity, not a greedy argument: the total of a stretch is the difference of two running totals, so "is there a stretch totalling `target` ending here" becomes "has the running total `sum - target` occurred before", answered by a map. Negative values, zeros and mixed signs are all ordinary inputs. It also counts ALL qualifying stretches, including overlapping ones, which the window fundamentally cannot do in one pass. What it costs: O(n) worst-case memory for the map — worst when the running totals never repeat — plus hashing work per element, and expected rather than worst-case constant-time lookups. On a memory-constrained embedded target or a very long stream, that difference is the whole argument. ## Choosing, out loud - Values are guaranteed non-negative, and you want the shortest or longest window meeting a threshold: **window**. O(1) state, cache-friendly, streaming, no allocation. - Any value may be negative or zero, or the question asks HOW MANY stretches hit an exact total: **prefix totals plus a map**. Correctness first; pay the memory. - Non-negative values but you need exact-total COUNTS including overlaps: the map is still the safer answer, because window-based counting on repeated sums is where subtle bugs live. The strongest interview answer names the assumption, not just the pattern: "a window is valid here only if every value is non-negative — is that guaranteed by the domain, or just true of the sample data?" That question is the point of the exercise. Domains where it is genuinely guaranteed (durations, byte counts, weights) invite the window; domains of signed deltas (ledger movements, temperature changes, sensor drift) forbid it. ## What a weak answer sounds like "Sliding window is O(1) space so it's better" — better only where it is correct. "You can fix the window by allowing the left pointer to move back" — that reintroduces the quadratic scan the window existed to avoid. "Sort the values first so they're positive-ordered" — sorting destroys contiguity and answers a different question entirely. And the reverse mistake is real too: reaching for a map on a strictly non-negative workload where a window would have been simpler, allocation-free and equally correct. ## The related-but-different variants Some threshold questions on signed data — shortest stretch whose total is at least a bound — need neither pattern in pure form: they combine running totals with a monotone structure over those totals. Knowing that such hybrids exist, and that the plain window is not among the fixes, is the differentiator between having memorised two templates and understanding what each one assumes.

  • The values are guaranteed non-negative. Which approach do you choose, and why not always default to the map?
    Choose the window: it is O(1) state, allocation-free, cache-friendly and works on a stream you cannot re-read, and with non-negative values its monotonicity assumption genuinely holds. Defaulting to the map costs O(n) memory and hashing per element for correctness you already had. The engineering habit worth showing is checking whether the guarantee is a domain invariant or merely a property of today's sample.
  • Can you rescue the window for signed values by letting the left pointer move backwards?
    Not usefully. Allowing the left pointer to retreat destroys the amortised argument that each pointer advances at most n times, and in the worst case you re-examine every left position for every right one — the quadratic scan the window existed to avoid. If sign is unconstrained, use the identity-based prefix approach rather than patching the greedy one.
  • What do zeros do to the window, given they are not negative?
    They preserve feasibility but weaken the guarantee from strictly increasing to non-decreasing, which matters for counting variants: a run of zeros produces many distinct stretches with the same total, and two-pointer counting either double-counts them or skips them depending on how the shrink loop is written. Existence questions survive zeros; exact-count questions are where the bugs appear.

A window search is like tuning a dial you believe only turns one way; a negative value secretly reverses the dial, so turning it further can take you back past the setting you wanted.

saying these in an interview costs you the question

  • Says a window works if you just move the left pointer back
  • Claims O(1) space makes the window the better choice regardless
  • Proposes sorting the values before applying a window
  • Treats the window's monotonicity as universal rather than sign-dependent
  • Reaches for the map on a strictly non-negative streaming workload

context