Continuous Subarray Sum
Medium · Math & Geometry · Explanation and code example
Prefix Sum + Hash Map
How it works
The key insight is based on modular arithmetic. If the prefix sum up to index i has remainder r when divided by k, and the prefix sum up to index j also has remainder r, then the subarray from i+1 to j has a sum that is a multiple of k. This is because (prefixSum[j] - prefixSum[i]) % k = 0 when both have the same remainder. We use a hash map to store the first index where each remainder was seen.
Steps
- Create a hash map to store remainder values and their first occurrence index. Initialize it with
{0: -1}to handle cases where the prefix sum itself is divisible byk. - Maintain a running total as we iterate through the array.
- For each element, add it to the total and compute the remainder (
total % k). - If this remainder exists in the map and the subarray length is at least 2 (current index minus stored index > 1), return
true. - If the remainder is not in the map, store it with the current index.
- Return
falseif no valid subarray is found.
Complexity
- Time complexity:
O(n) - Space complexity:
O(k)
Where
nis the size of the arraynumsandkis the number that a subarray sum needs to be multiple of.
Things to watch for
Forgetting to Initialize Hash Map with {0: -1}
The hash map must be initialized with remainder 0 at index -1 to handle cases where the prefix sum itself (from index 0 to current) is divisible by k. Without this, you miss valid subarrays that start from index 0.
Not Enforcing Minimum Subarray Length of 2
The problem requires the subarray to have at least 2 elements. A common mistake is checking i - remainder[r] >= 1 instead of > 1, which would accept single-element subarrays.
Updating the Hash Map When Remainder Already Exists
When the same remainder is seen again, you should NOT update its index. We need the earliest index for each remainder to maximize the subarray length and correctly detect valid subarrays. Updating would shrink the window and potentially miss valid answers.
Python code example
from typing import List
class Solution:
def checkSubarraySum(self, nums: List[int], k: int) -> bool:
remainder = {0: -1} # remainder -> end index
total = 0
for i, num in enumerate(nums):
total += num
r = total % k
if r not in remainder:
remainder[r] = i
elif i - remainder[r] > 1:
return True
return False
C++ code example
class Solution {
public:
bool checkSubarraySum(vector<int>& nums, int k) {
unordered_map<int, int> remainder;
remainder[0] = -1;
int total = 0;
for (int i = 0; i < nums.size(); i++) {
total += nums[i];
int r = total % k;
if (remainder.find(r) == remainder.end()) {
remainder[r] = i;
} else if (i - remainder[r] > 1) {
return true;
}
}
return false;
}
};
Source and license
Adapted from NeetCode’s source · MIT license. Node types are supplied by LeetCode where needed.