Given an unsorted array of integers, find the number of continuous subarrays having sum exactly equal to a given number k.
Examples:
Input: arr = [10, 2, -2, -20, 10], k = -10 Output: 3 Explaination: Subarrays: arr[0...3], arr[1...4], arr[3...4] have sum exactly equal to -10.
Input: arr = [9, 4, 20, 3, 10, 5], k = 33 Output: 2 Explaination: Subarrays: arr[0...2], arr[2...4] have sum exactly equal to 33.
Input: arr = [1, 3, 5], k = 0
Output: 0 Explaination: No subarray with 0 sum.
Constraints:
- 1 ≤ arr.size() ≤ 105
- -103 ≤ arr[i] ≤ 103
- -107 ≤ k ≤ 107
Approach 01:
-
C++
-
Python
#include <vector> #include <unordered_map> using namespace std; class Solution { public: int countSubarrays(vector<int>& nums, int targetSum) { unordered_map<int, int> prefixSumFrequency; int currentPrefixSum = 0; int subarrayCount = 0; // Initialize the map with prefix sum 0 having frequency 1 prefixSumFrequency[0] = 1; for (int num : nums) { currentPrefixSum += num; // Check if there exists a prefix sum such that currentPrefixSum - prefixSum = targetSum if (prefixSumFrequency.find(currentPrefixSum - targetSum) != prefixSumFrequency.end()) { subarrayCount += prefixSumFrequency[currentPrefixSum - targetSum]; } // Update the frequency of the current prefix sum in the map ++prefixSumFrequency[currentPrefixSum]; } return subarrayCount; } };
from typing import List from collections import defaultdict class Solution: def countSubarrays(self, nums: List[int], targetSum: int) -> int: prefixSumFrequency = defaultdict(int) currentPrefixSum = 0 subarrayCount = 0 # Initialize the dictionary with prefix sum 0 having frequency 1 prefixSumFrequency[0] = 1 for num in nums: currentPrefixSum += num # Check if there exists a prefix sum such that currentPrefixSum - prefixSum = targetSum if currentPrefixSum - targetSum in prefixSumFrequency: subarrayCount += prefixSumFrequency[currentPrefixSum - targetSum] # Update the frequency of the current prefix sum in the dictionary prefixSumFrequency[currentPrefixSum] += 1 return subarrayCount
Time Complexity:
- Single Iteration:
- We iterate through the array once, performing a constant amount of work for each element.
- The prefix sum calculation, map lookup, and insertion all take \( O(1) \) on average.
- For \( n \) elements in the array, this contributes \( O(n) \) to the time complexity.
- Overall Time Complexity:
\( O(n) \), where \( n \) is the size of the input array.
Space Complexity:
- Prefix Sum Map:
- The map stores at most \( n + 1 \) entries (one for each prefix sum and the initial 0 prefix sum).
- Each entry in the map requires constant space.
- The space used by the map is \( O(n) \).
- Auxiliary Variables:
- We use a few additional variables: \( currentPrefixSum \), \( subarrayCount \), and a loop counter, which all take \( O(1) \) space.
- Overall Space Complexity:
\( O(n) \), dominated by the space used by the prefix sum map.