Problem Statement
Given an array of integers nums and an integer k, return the total number of continuous subarrays whose sum equals k.
Example 1:
- Input:
nums = [1, 1, 1],k = 2 - Output:
2
Example 2:
- Input:
nums = [1, 2, 3],k = 3 - Output:
2
Constraints:
Brute Force:
Intuition
A subarray is defined by a start index and an end index. To check every possible subarray:
- We pick a starting point for the subarray.
- We iterate through every possible ending point starting from to the end of the array.
- For every range , we calculate the sum of elements and check if that sum is equal to .
Since we are checking all pairs , there are possible subarrays.
Algorithm
- Initialize a counter
count = 0. - Use an outer loop with index from to (the start of the subarray).
- Inside, maintain a variable
current_sum = 0. - Use an inner loop with index from to (the end of the subarray).
- Add
nums[j]tocurrent_sum. - If
current_sum == k, incrementcount. - Return
countafter all loops finish.
def subarraySum(nums, k):
count = 0
n = len(nums)
# Outer loop for start index
for i in range(n):
current_sum = 0
# Inner loop for end index
for j in range(i, n):
current_sum += nums[j]
# Check if condition is met
if current_sum == k:
count += 1
return countDry Run
============================================================
DRY RUN: Subarray Sum Equals K (Brute Force)
Input: nums = [1, 2, 3], k = 3
============================================================
[Phase 1: Starting at index 0]
i=0, j=0: Subarray [1] | Sum = 1
i=0, j=1: Subarray [1, 2] | Sum = 3 >> MATCH FOUND!
i=0, j=2: Subarray [1, 2, 3] | Sum = 6
[Phase 2: Starting at index 1]
i=1, j=1: Subarray [2] | Sum = 2
i=1, j=2: Subarray [2, 3] | Sum = 5
[Phase 3: Starting at index 2]
i=2, j=2: Subarray [3] | Sum = 3 >> MATCH FOUND!
============================================================
Total Count: 2
============================================================Complexity Analysis
- Time Complexity: because we have nested loops iterating through the array.
- Space Complexity: as we only use a few variables for counting and summing.
Optimal approach
Imagine you are walking along the array, keeping a running total called current_sum.
- The Goal: We want to find a subarray that sums to
k. Mathematically, this means: - The Rearrangement: If we move to the other side, we get:
- The "Aha!" Moment: As we iterate through the array, at any point
j, we know our current total (PrefixSum_j). We just need to check: "Have I seen a previous prefix sum that equalscurrent_sum - k?" * If the answer is Yes, it means the elements between that previous point and the current point must sum exactly tok.
The Hash Map Strategy
Instead of using a nested loop to re-calculate sums, we use a Hash Map (Dictionary) to store every PrefixSum we encounter and how many times we have seen it.
- Key: The
PrefixSumvalue. - Value: How many times this
PrefixSumhas occurred so far.
To implement the optimal solution, we use a Hash Map (or dictionary) to keep track of the prefix sums encountered so far.
The Algorithm
- Initialize Variables:
count = 0: To keep track of the number of valid subarrays found.current_sum = 0: To store the running total of elements.prefix_sums = {0: 1}: A dictionary (hash map) initialized with{0: 1}. This handles cases where a subarray starting from index 0 equalsk.
- Iterate Through the Array:
- For each element
numin the array:- Update
current_sumby addingnum. - Check for Complement: Calculate
target = current_sum - k. - If
targetexists in theprefix_sumsdictionary, it means there is a subarray that sums tok. Add the frequency oftargettocount. - Update Map: Store or increment the
current_sumin theprefix_sumsdictionary to make it available for future lookups.
- Update
- For each element
- Return:
- After iterating through the entire array, return
count.
- After iterating through the entire array, return
C++ code:
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int count = 0;
int current_sum = 0;
unordered_map<int, int> prefix_sums;
// Base case: a prefix sum of 0 has occurred once
prefix_sums[0] = 1;
for (int num : nums) {
current_sum += num;
// If (current_sum - k) exists, we found valid subarrays
if (prefix_sums.count(current_sum - k)) {
count += prefix_sums[current_sum - k];
}
// Record the current prefix sum in the map
prefix_sums[current_sum]++;
}
return count;
}
};Dry Run:

1. Time Complexity:
- Single Traversal: We iterate through the array of elements exactly once.
- Constant Time Lookups: Inside the loop, we perform dictionary operations (
findorcount) and updates (insertorincrement). In C++,unordered_mapprovides an average time complexity for these operations. - Total Calculation: Since we perform a constant number of operations for each of the elements, the overall time complexity is .
2. Space Complexity:
- Hash Map Storage: In the worst-case scenario (e.g., an array where every prefix sum is unique), we will store a new entry in the
unordered_mapfor every element we process. - Total Calculation: This results in a space requirement that grows linearly with the input size, leading to space complexity.
problem :
Subarray Sum Equals K - LeetCode
video reference:
