Subarray Sum Equals K
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.
| Approach | Time | Space |
|---|---|---|
| Brute force | O(n²) | O(1) |
| Optimal (prefix sum + hash map) | O(n) | O(n) |
1Brute force
O(n²)O(1)For each start, extend the end with a running sum and count sums equal to k.
- For each i, sum = 0; for j from i, sum += nums[j]; if sum == k, count++.
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)
O(n)O(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.
- freq = {0: 1} to count subarrays starting at index 0.
- For each x: prefix += x; count += freq[prefix - k]; freq[prefix]++.
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).