You've implemented the prefix sum + hash map solution for Subarray Sum Equals K. It works on the examples. You submit.
Wrong Answer on test case 47/93.
You stare at your code. It looks correct. The logic makes sense. But somewhere, there's a bug.
Sound familiar? Debugging prefix sum + hash map solutions is tricky because the bugs are subtle. A missing initialization, wrong update order, or incorrect handling of edge cases can cause failures on specific test cases.
In this guide, you'll learn the step-by-step debugging process, common bugs and their symptoms, and how to trace through examples to find and fix issues fast.
TL;DR
Common bugs:
- Missing {0: 1} initialization → Fails on subarrays from index 0
- Wrong update order → Counts current element incorrectly
- Counting vs finding indices → Using wrong template
- Negative numbers → Unexpected behavior with sliding window mindset
Debugging process:
- Trace with small example
- Check hash map state at each step
- Verify prefix sum calculation
- Test edge cases
Common Bug 1: Not Initializing {0: 1}
Symptom
Solution fails on test cases where the answer includes subarrays starting from index 0.
Example That Fails
# BUGGY CODE
def subarraySum(nums, k):
count = 0
prefix_sum = 0
sum_count = {} # BUG: Missing {0: 1}
for num in nums:
prefix_sum += num
if prefix_sum - k in sum_count:
count += sum_count[prefix_sum - k]
sum_count[prefix_sum] = sum_count.get(prefix_sum, 0) + 1
return count
# Test
print(subarraySum([1, 2, 3], 6)) # Expected: 1, Got: 0 ❌
print(subarraySum([1, 1, 1], 2)) # Expected: 2, Got: 1 ❌The Fix
# FIXED CODE
def subarraySum(nums, k):
count = 0
prefix_sum = 0
sum_count = {0: 1} # ✓ Initialize with base case
for num in nums:
prefix_sum += num
if prefix_sum - k in sum_count:
count += sum_count[prefix_sum - k]
sum_count[prefix_sum] = sum_count.get(prefix_sum, 0) + 1
return count
# Test
print(subarraySum([1, 2, 3], 6)) # 1 ✓
print(subarraySum([1, 1, 1], 2)) # 2 ✓Why It Works
The {0: 1} represents seeing prefix_sum = 0 once before processing any elements. This allows detection of subarrays starting from index 0.
See detailed guide: Hash Map Initialization
Common Bug 2: Updating Hash Map Too Early
Symptom
Solution counts extra subarrays or gives incorrect counts.
Example That Fails
# BUGGY CODE
def subarraySum(nums, k):
count = 0
prefix_sum = 0
sum_count = {0: 1}
for num in nums:
prefix_sum += num
sum_count[prefix_sum] = sum_count.get(prefix_sum, 0) + 1 # BUG: Update first
if prefix_sum - k in sum_count: # Then check
count += sum_count[prefix_sum - k]
return count
# Test
print(subarraySum([1], 0)) # Expected: 0, Got: 1 ❌Why It's Wrong
Trace for nums = [1], k = 0:
Initial: sum_count = {0: 1}, prefix_sum = 0
i=0: num=1
prefix_sum = 1
Update: sum_count = {0: 1, 1: 1}
Check: (1 - 0) = 1 in sum_count? Yes!
count += sum_count[1] = 1
Result: 1 (WRONG! No subarray has sum 0)The bug: We added prefix_sum = 1 to the map, then immediately found it when checking for prefix_sum - k = 1. This incorrectly counts the current element as a valid subarray.
The Fix
# FIXED CODE
def subarraySum(nums, k):
count = 0
prefix_sum = 0
sum_count = {0: 1}
for num in nums:
prefix_sum += num
if prefix_sum - k in sum_count: # ✓ Check first
count += sum_count[prefix_sum - k]
sum_count[prefix_sum] = sum_count.get(prefix_sum, 0) + 1 # Then update
return count
# Test
print(subarraySum([1], 0)) # 0 ✓The Rule
Always check before update to avoid counting the current element incorrectly.
Common Bug 3: Counting vs Finding Indices
Symptom
Using the wrong template for the problem type.
Problem Type 1: Counting Subarrays
Correct approach: Store frequency, update every time
def subarraySum(nums, k):
count = 0
prefix_sum = 0
sum_count = {0: 1} # Frequency
for num in nums:
prefix_sum += num
if prefix_sum - k in sum_count:
count += sum_count[prefix_sum - k] # Add frequency
sum_count[prefix_sum] = sum_count.get(prefix_sum, 0) + 1 # Always update
return countProblem Type 2: Finding Longest Subarray
Correct approach: Store earliest index, update only if not seen
def maxSubArrayLen(nums, k):
max_len = 0
prefix_sum = 0
sum_index = {0: -1} # Earliest index
for i, num in enumerate(nums):
prefix_sum += num
if prefix_sum - k in sum_index:
max_len = max(max_len, i - sum_index[prefix_sum - k])
# Only store if not seen before (keep earliest)
if prefix_sum not in sum_index:
sum_index[prefix_sum] = i
return max_lenCommon Mistake
❌ Using counting template for finding longest:
# WRONG: Always updating index
sum_index[prefix_sum] = i # Should only update if not seenThis keeps the latest index instead of the earliest, giving shorter subarrays.
Common Bug 4: Handling Negative Numbers
Symptom
Solution works for positive numbers but fails with negatives.
Why Negatives Are Tricky
With positive numbers only, you might think sliding window works. But with negative numbers, prefix sums can decrease, breaking sliding window assumptions.
Example
nums = [1, -1, 5, -2, 3], k = 3
Prefix sums: 0, 1, 0, 5, 3, 6
Notice: prefix_sum goes 1 → 0 (decreased!)
This is why sliding window fails with negatives.The Fix
Use prefix sum + hash map, which handles negatives correctly:
def subarraySum(nums, k):
count = 0
prefix_sum = 0
sum_count = {0: 1}
for num in nums:
prefix_sum += num # Can increase or decrease
if prefix_sum - k in sum_count:
count += sum_count[prefix_sum - k]
sum_count[prefix_sum] = sum_count.get(prefix_sum, 0) + 1
return count
# Test with negatives
print(subarraySum([1, -1, 5, -2, 3], 3)) # Works correctlySee detailed guide: Negative Numbers
Step-by-Step Debugging Process
Step 1: Trace with Small Example
Pick a simple test case and trace through manually.
Example: nums = [1, 2, 3], k = 3
Initial: sum_count = {0: 1}, prefix_sum = 0, count = 0
i=0: num=1
prefix_sum = 0 + 1 = 1
Check: (1 - 3) = -2 in {0: 1}? No
sum_count = {0: 1, 1: 1}
count = 0
i=1: num=2
prefix_sum = 1 + 2 = 3
Check: (3 - 3) = 0 in {0: 1, 1: 1}? Yes!
count += sum_count[0] = 0 + 1 = 1
Found subarray [1, 2]
sum_count = {0: 1, 1: 1, 3: 1}
count = 1
i=2: num=3
prefix_sum = 3 + 3 = 6
Check: (6 - 3) = 3 in {0: 1, 1: 1, 3: 1}? Yes!
count += sum_count[3] = 1 + 1 = 2
Found subarray [3]
sum_count = {0: 1, 1: 1, 3: 1, 6: 1}
count = 2
Result: 2 ✓
Subarrays: [1, 2] and [3]Step 2: Check Hash Map State
At each iteration, verify:
- Is the hash map correct?
- Does it contain expected values?
- Are frequencies/indices accurate?
Add debug prints:
for num in nums:
prefix_sum += num
print(f"num={num}, prefix={prefix_sum}, map={sum_count}")
if prefix_sum - k in sum_count:
count += sum_count[prefix_sum - k]
print(f" Found! count={count}")
sum_count[prefix_sum] = sum_count.get(prefix_sum, 0) + 1Step 3: Verify Prefix Sum Calculation
Check that prefix_sum is being calculated correctly:
- Is it cumulative?
- Does it handle negatives?
- Is it reset anywhere (it shouldn't be)?
Step 4: Test Edge Cases
Edge case checklist:
# Empty array
assert subarraySum([], 0) == 0
# Single element (match)
assert subarraySum([5], 5) == 1
# Single element (no match)
assert subarraySum([5], 3) == 0
# All zeros
assert subarraySum([0, 0, 0], 0) == 6 # All subarrays
# Negative numbers
assert subarraySum([1, -1, 0], 0) == 3
# Target = 0
assert subarraySum([1, -1, 1, -1], 0) == 4
# Entire array
assert subarraySum([1, 2, 3], 6) == 1The Correct Template
For Counting Subarrays
def subarraySum(nums: List[int], k: int) -> int:
"""
Count subarrays with sum equal to k.
Time: O(n), Space: O(n)
"""
count = 0
prefix_sum = 0
sum_count = {0: 1} # Critical: base case
for num in nums:
prefix_sum += num
# Check BEFORE update
if prefix_sum - k in sum_count:
count += sum_count[prefix_sum - k]
# Update frequency
sum_count[prefix_sum] = sum_count.get(prefix_sum, 0) + 1
return countFor Finding Longest Subarray
def maxSubArrayLen(nums: List[int], k: int) -> int:
"""
Find longest subarray with sum equal to k.
Time: O(n), Space: O(n)
"""
max_len = 0
prefix_sum = 0
sum_index = {0: -1} # Critical: index before start
for i, num in enumerate(nums):
prefix_sum += num
if prefix_sum - k in sum_index:
max_len = max(max_len, i - sum_index[prefix_sum - k])
# Only store if not seen (keep earliest)
if prefix_sum not in sum_index:
sum_index[prefix_sum] = i
return max_lenReal Debugging Example
The Bug
# Student's code (has a bug)
def subarraySum(nums, k):
count = 0
prefix_sum = 0
sum_count = {0: 1}
for num in nums:
if prefix_sum - k in sum_count: # BUG: Check before update
count += sum_count[prefix_sum - k]
prefix_sum += num # BUG: Update after check
sum_count[prefix_sum] = sum_count.get(prefix_sum, 0) + 1
return countFinding the Bug
Test case: nums = [1], k = 1
Expected: 1 (the subarray [1])
Got: 0
Trace:
Initial: sum_count = {0: 1}, prefix_sum = 0, count = 0
i=0: num=1
Check: (0 - 1) = -1 in {0: 1}? No ← Checking with old prefix_sum!
prefix_sum = 0 + 1 = 1 ← Update after check
sum_count = {0: 1, 1: 1}
count = 0
Result: 0 (WRONG!)The issue: We check with the old prefix_sum (0), then update to the new prefix_sum (1). We should update first, then check.
The Fix
# FIXED CODE
def subarraySum(nums, k):
count = 0
prefix_sum = 0
sum_count = {0: 1}
for num in nums:
prefix_sum += num # ✓ Update first
if prefix_sum - k in sum_count: # ✓ Then check
count += sum_count[prefix_sum - k]
sum_count[prefix_sum] = sum_count.get(prefix_sum, 0) + 1
return countDebugging Checklist
When your solution fails, check:
-
Initialization: Did you add
{0: 1}or{0: -1}? -
Update order: Check before update, not after?
-
Prefix sum calculation: Is it cumulative? Updated correctly?
-
Template type: Counting (frequency) or finding (index)?
-
Edge cases: Empty array, single element, all zeros, negatives?
-
Hash map type: Using dict/map, not set?
-
Return value: Returning count/length, not the hash map?
Practice Problems
Debug your skills with these problems:
Beginner:
- Subarray Sum Equals K (#560) - Basic template
- Running Sum of 1d Array (#1480) - Simpler variant
Intermediate:
3. Continuous Subarray Sum (#523) - Modulo arithmetic
4. Contiguous Array (#525) - Transform to sum = 0
5. Maximum Size Subarray Sum Equals k (#325) - Finding longest
Advanced:
6. Subarray Sums Divisible by K (#974) - Negative remainders
7. Count Number of Nice Subarrays (#1248) - Transform problem
FAQ
Q: My solution works on examples but fails on submission. What should I check first?
A: Check initialization ({0: 1}) and edge cases (empty array, single element, negatives).
Q: How do I know if I should use {0: 1} or {0: -1}?
A: Counting subarrays → {0: 1}. Finding longest → {0: -1}. See Hash Map Initialization.
Q: My solution gives a count that's too high. What's wrong?
A: Likely updating the hash map before checking. Always check first, then update.
Q: My solution gives a count that's too low. What's wrong?
A: Likely missing {0: 1} initialization, which causes you to miss subarrays from index 0.
Q: How do I debug if I can't see the failing test case?
A: Create your own edge cases:
- Empty array
- Single element (match and no match)
- All same values
- Negative numbers
- Target = 0
- Entire array sums to target
Q: Should I use a set or a dict/map?
A: Use dict/map to store frequency or index. Use set only for existence checks (rare).
Conclusion
Debugging prefix sum + hash map solutions requires systematic thinking and understanding of common pitfalls.
Key debugging steps:
- Trace manually with a small example
- Check hash map state at each iteration
- Verify prefix sum calculation
- Test edge cases thoroughly
Common bugs:
- Missing
{0: 1}initialization - Wrong update order (update before check)
- Using wrong template (counting vs finding)
- Not handling negatives correctly
The correct template:
count = 0
prefix_sum = 0
sum_count = {0: 1} # Initialize
for num in nums:
prefix_sum += num # Update
if prefix_sum - k in sum_count: # Check
count += sum_count[prefix_sum - k]
sum_count[prefix_sum] = sum_count.get(prefix_sum, 0) + 1 # Store
return countMaster this debugging process, and you'll fix prefix sum bugs in minutes. For more on this pattern, see Prefix Sum + Hash Map, Hash Map Initialization, and the complete guide.
Next time your solution fails, trace it step-by-step. The bug will reveal itself.
Want to Practice LeetCode Smarter?
LeetCopilot is a free browser extension that enhances your LeetCode practice with AI-powered hints, personalized study notes, and realistic mock interviews — all designed to accelerate your coding interview preparation.
Also compatible with Edge, Brave, and Opera
