Command Palette

Search for a command to run...

Lesson 5.2 · Prefix Sum

Prefix Sums with a Hash Map

A subarray sums to k exactly when two prefix sums differ by k, so count earlier prefix sums equal to current − k with a hash map.

15 min

Think of it like this

Your bank balance after each day is a running total. If any stretch of days added exactly ₹500, then today's balance minus ₹500 equals some earlier day's balance. Keep a list of every balance you've had, and you can spot such stretches the moment they end.

1.The key equation

The sum of a[i..j] is prefix[j + 1] − prefix[i]. It equals k exactly when prefix[i] = prefix[j + 1] − k. So while scanning, for the current running sum sum, the number of subarrays ending here with sum k is the number of earlier prefix sums equal to sum − k.

Store how many times each prefix sum has occurred in a map. Seed it with {0: 1} for the empty prefix, so subarrays starting at index 0 are counted.

▶ Dry run: Counting subarrays with sum 3a = [1, 2, 1, -1, 2], k = 3
1
0
2
1
1
2
-1
3
2
4

seen (prefix sum → count)(map)

0 → 1

State(vars)

sum = 0count = 0

Step 1/6Start: the empty prefix has sum 0, seen once.

2.The same idea in code

Five lines inside the loop: add the element to sum, count earlier prefix sums equal to sum − k, then record sum. Running it on the traced input prints 3. When you trace by hand, checking against real output like this catches arithmetic slips.

CountK.java
import java.util.HashMap;
import java.util.Map;

public class Main {
    static int subarraySum(int[] a, int k) {
        Map<Integer, Integer> seen = new HashMap<>();
        seen.put(0, 1);
        int sum = 0, count = 0;
        for (int x : a) {
            sum += x;
            count += seen.getOrDefault(sum - k, 0);
            seen.merge(sum, 1, Integer::sum);
        }
        return count;
    }
    public static void main(String[] args) {
        System.out.println(subarraySum(new int[]{1, 2, 1, -1, 2}, 3));
    }
}

Output

3

3.Why not a sliding window?

A sliding window works when growing the window always increases the sum (all positives). With negatives, shrinking the window can increase the sum, so the window rule breaks. Prefix sums with a hash map don't care about signs.

Remember

  • Subarray sum k ⇔ two prefix sums differ by k.
  • Count earlier prefix sums equal to sum − k.
  • Seed the map with {0: 1}.
  • Works with negative numbers, unlike sliding windows.

Common mistakes

  • Forgetting the {0: 1} seed, which misses subarrays starting at index 0.
  • Updating the map before counting, which can count an empty subarray when k = 0.