Subarray Sum Equals K medium
Problem Statement
Given an array of integers nums
and an integer k
, return the total number of continuous subarrays whose sum equals to k
.
Example 1:
Input: nums = [1,1,1], k = 2 Output: 2
Explanation:
The subarrays are: [1,1] and [1,1]
Example 2:
Input: nums = [1,2,3], k = 3 Output: 2
Explanation:
The subarrays are: [3] and [1,2]
Steps
-
Prefix Sum: We'll use a
prefixSum
map to store the cumulative sum of elements encountered so far and their frequency. The key is the cumulative sum, and the value is the count of times that sum has appeared. We initialize the map with a0
sum having a count of1
because an empty subarray (before we've even started) has a sum of 0. -
Iteration: We iterate through the
nums
array. In each iteration, we calculate the current cumulative sum (currentSum
). -
Check for k: We check if
currentSum - k
exists as a key in theprefixSum
map. If it does, it means there was a previous subarray whose sum wascurrentSum - k
. Adding the current element to this previous subarray will result in a subarray with a sum ofk
. We add the frequency ofcurrentSum - k
to ourcount
of subarrays. -
Update Prefix Sum: We update the
prefixSum
map by incrementing the count for thecurrentSum
. -
Return Count: Finally, we return the
count
of subarrays that sum tok
.
Explanation
The core idea is to efficiently find subarrays that sum to k
. Instead of checking every possible subarray (which would be O(n^2)), we leverage the prefix sum technique. By keeping track of cumulative sums and their frequencies, we can quickly determine if a subarray with the desired sum exists by checking if currentSum - k
is present in the prefixSum
map. This drastically reduces the time complexity.
Code
function subarraySum(nums: number[], k: number): number {
const prefixSum = new Map<number, number>();
prefixSum.set(0, 1); // Initialize for empty subarray
let currentSum = 0;
let count = 0;
for (const num of nums) {
currentSum += num;
if (prefixSum.has(currentSum - k)) {
count += prefixSum.get(currentSum - k)!;
}
prefixSum.set(currentSum, (prefixSum.get(currentSum) || 0) + 1);
}
return count;
}
Complexity
-
Time Complexity: O(n), where n is the length of the input array. We iterate through the array once. Map operations (get and set) are typically O(1) on average.
-
Space Complexity: O(n) in the worst case. The
prefixSum
map could potentially store up to n distinct cumulative sums. In the best case (many repeated sums), it could be much smaller.