Foundation · Module 5 · Lesson 4

Prefix sum + hash map

Track prior states to count subarrays.

15–25 min readLesson 30 of 123

Lesson 30 of 123

1d streak

Prefix Sum + HashMap: Finding Subarrays Summing to K in O(n)

Finding whether an array contains a contiguous subarray summing to k naively takes $O(n^2)$ by checking all pairs. By combining Prefix Sums with a HashMap, we reduce the search to O(n) time and O(n) space using a two-sum variation.

The Mathematical Insight Behind Subarray Sum Equals K
Let prefixSum[i] = sum of elements from 0 to i.
The sum of subarray from index (j + 1) to i is:
    subarraySum(j+1, i) = prefixSum[i] - prefixSum[j]

We want:
    prefixSum[i] - prefixSum[j] == k
Rearranging:
    prefixSum[j] == prefixSum[i] - k

Insight:
At each index i, we check if the HashMap has previously seen (prefixSum[i] - k)!
If it has, that earlier index j marks the start of a valid subarray summing to k!
SubarraySumEqualsK.java
public int subarraySum(int[] nums, int k) {
    Map<Integer, Integer> prefixCounts = new HashMap<>();
    prefixCounts.put(0, 1); // Base case: prefix sum of 0 occurred once before array starts

    int runningSum = 0;
    int count = 0;

    for (int num : nums) {
        runningSum += num;
        // Check if there is an earlier prefix sum that leaves a remainder of k
        if (prefixCounts.containsKey(runningSum - k)) {
            count += prefixCounts.get(runningSum - k);
        }
        prefixCounts.put(runningSum, prefixCounts.getOrDefault(runningSum, 0) + 1);
    }
    return count;
}

Active Recall Checkpoint

Why must prefixCounts.put(0, 1) be initialized before the loop in Subarray Sum Equals K?

Hint: Consider what happens when a prefix from index 0 to i itself sums exactly to k.

Show answer & explanation

If a prefix from index 0 to i equals k, runningSum - k evaluates to 0. Without prefixCounts.put(0, 1), this valid subarray starting at index 0 would not be counted.

Cost Model

Complexity & Trade-offs

Count matching ranges
Expected O(n)
O(n)
The bound follows from the number of states visited and the work performed per transition.

When to use it

  • Presence, uniqueness, frequency, complement, and previously seen state queries.
  • Replacing repeated scans with indexed history.
  • Grouping values by a canonical key.

Common mistakes

  • Assuming hash lookup has a deterministic O(1) worst case.
  • Updating the map before a query that requires a distinct earlier item.
  • Using mutable or inconsistent keys.

Practice prompts

  • Reproduce the worked Prefix sum + hash map example without looking at the trace.
  • Change one input condition and explain whether the Prefix sum + hash map invariant still holds.
  • Implement the approach, derive its cost, and compare it with a straightforward baseline.

Mastery check

Can you derive it instead of memorizing it?

State the invariant before looking at code.
Explain why every transition is safe.
Construct a worst-case input.
Name one alternative and its trade-off.