Subarray Sum Equals K

Medium Arrays & Hashing Prefix Sum Strategy Original on LeetCode

Subarray Sum Equals K is a medium arrays & hashing problem solved with the prefix sum strategy pattern. The best approach, optimal (prefix sum + hash map), runs in O(n) time and O(n) space. Below are 2 approaches in Java, from brute force up.

Problem

Given an integer array nums (it may contain negatives) and an integer k, return the number of contiguous subarrays whose sum equals k.

Examples

Example 1

Input
nums = [1, 2, 1, 2], k = 3
Output
3
Why
[1,2], [2,1] and [1,2] again (indices 2..3).

Example 2

Input
nums = [1, -1, 0], k = 0
Output
3
Why
[1,-1], [0] and [1,-1,0].

Constraints

  • 1 <= nums.length <= 2 * 10^4
  • -1000 <= nums[i] <= 1000
  • Negative numbers are allowed, so a sliding window will not work.

Animated walkthrough

A narrated, step-by-step animation that builds the solution from the idea up. Press play, or step through it at your own pace.

Concepts first, then the problem and every approach, step by step.

Space to play or pause · ← → to jump a step · click or drag the bar to seek

Solutions

Try it yourself first. Then compare: each approach lists its idea, the steps, its time and space, and the Java code.

ApproachTimeSpace
Brute forceO(n²)O(1)
Optimal (prefix sum + hash map)O(n)O(n)

1Brute force

TimeO(n²)
SpaceO(1)

For each start, extend the end with a running sum and count sums equal to k.

  1. For each i, sum = 0; for j from i, sum += nums[j]; if sum == k, count++.
Java
class Solution {
    public int subarraySum(int[] nums, int k) {
        int count = 0;
        for (int i = 0; i < nums.length; i++) {
            int sum = 0;
            for (int j = i; j < nums.length; j++) {
                sum += nums[j];
                if (sum == k) count++;
            }
        }
        return count;
    }
}

2Optimal (prefix sum + hash map)

TimeO(n)
SpaceO(n)

Keep a running prefix sum and a map from prefix value to how many times it has occurred. A subarray ending here sums to k exactly when an earlier prefix equals prefix - k, so add that frequency.

  1. freq = {0: 1} to count subarrays starting at index 0.
  2. For each x: prefix += x; count += freq[prefix - k]; freq[prefix]++.
Java
class Solution {
    public int subarraySum(int[] nums, int k) {
        Map<Integer, Integer> freq = new HashMap<>();
        freq.put(0, 1);
        int prefix = 0, count = 0;
        for (int x : nums) {
            prefix += x;
            count += freq.getOrDefault(prefix - k, 0);
            freq.merge(prefix, 1, Integer::sum);
        }
        return count;
    }
}

Edge cases to test

  • k = 0
  • Negative numbers
  • The subarray starts at index 0 (needs prefix 0 counted once up front)

Hints

Hint 1

sum(i..j) = prefix[j] - prefix[i - 1]. So for each j, how many earlier prefixes equal prefix[j] - k?

FAQ

What is the best time complexity for Subarray Sum Equals K?

Optimal (prefix sum + hash map) runs in O(n) time and O(n) extra space.

Which pattern does Subarray Sum Equals K use?

It is a arrays & hashing problem that uses the prefix sum strategy pattern. Other problems with the same pattern: Subarray with given XOR, Range Sum Query - Immutable.

Is there a brute force solution for Subarray Sum Equals K?

Yes. Brute force takes O(n²) time and O(1) space. For each start, extend the end with a running sum and count sums equal to k.

Which edge cases should I test for Subarray Sum Equals K?

k = 0; Negative numbers; The subarray starts at index 0 (needs prefix 0 counted once up front).