You learned the Sliding Window pattern. You memorized the template.
Then you tried to solve "Subarray Sum Equals K" with negative numbers.
And it failed.
Why? The algorithm relies on a hidden assumption: Monotonicity. Negative numbers break this assumption, shattering the logic of the greedy window.
TL;DR — The Monotonicity Rule
- Mixed Signs (+ and -): Sliding Window FAILS. Use Prefix Sum.
- All Positive: Sliding Window WORKS.
- All Negative: Sliding Window WORKS (but usually trivial).
- Max Sum Subarray (Any signs): Use Kadane's Algorithm ().
Why negative numbers break assumptions
Standard Sliding Window logic:
- Sum too small? Expand
rightto make it bigger. - Sum too big? Shrink
leftto make it smaller.
With Negative Numbers:
- Current Sum = 10. Target = 15.
- Expand
right(add -5). New Sum = 5. - Wait. We expanded, but the sum got smaller.
- Should we expand again? Or shrink? We don't know. The direction of change is no longer predictable.
Example problem
Target K = 5
Window: [10, -2] (Sum = 8).
- Logic says: "Sum > 5, so shrink left."
- We shrink (remove 10). Window:
[-2](Sum = -2). - We missed the fact that maybe the next number was
-3, making[10, -2, -3]= 5. - By greedily shrinking, we cut off a potential valid path.
Alternative techniques
Since we can't use the greedy 2-pointer window, we need techniques that handle non-monotonic data.
1. Prefix Sum + Hash Map (The Gold Standard)
- Calculate running sum.
- Store
{ sum: count }in a Hash Map. - Check if
(CurrentSum - K)exists in the map. - Complexity: Time, Space.
2. Two Pointers + Sorting (If order doesn't matter)
- If the problem asks for "Two Sum" (pairs) and order is irrelevant, you can sort the array.
- Sorting destroys the subarray structure, so this only works for subset or pair problems, not subarrays.
Hybrid approach: convert negative case
Sometimes you can transform the problem.
- "Longest subarray with equal 0s and 1s":
- Treat 0 as -1.
- Now find longest subarray with Sum = 0.
- Use Prefix Sum Map.
Code template: detecting negative input
In an interview, you can write a helper to switch strategies.
function solveSubarraySum(nums: number[], k: number) {
const hasNegatives = nums.some(n => n < 0);
if (hasNegatives) {
return solveWithPrefixSum(nums, k);
} else {
return solveWithSlidingWindow(nums, k);
}
}Note: Usually you just implement the Prefix Sum version as it handles both, but mentioning this distinction shows deep understanding.
FAQ
Q: What if the numbers are ALL negative?
A: If all numbers are negative, the problem is actually monotonic again (adding an element always decreases the sum). Standard Sliding Window logic can work for certain conditions, but usually, you just want the single largest element (closest to 0).
Q: Can I use Sliding Window if I just want the maximum sum subarray?
A: Yes! This is Kadane's Algorithm. It is technically a dynamic sliding window where you reset the window whenever the current prefix sum becomes negative. It works perfectly with negative numbers because it resets rather than shrinks.
Summary
- Sliding Window requires Monotonicity (Sum always grows with expansion).
- Negative Numbers break Monotonicity.
- The Fix: Use Prefix Sums.
Next Step:
Another area where Sliding Window fails is stock trading. Find out why in Why Sliding Window Doesn’t Work on Stock Problems.
Ready to Practice This Pattern?
Apply this pattern with LeetCopilot's AI-powered hints, notes, and mock interviews. Transform your coding interview preparation today.
