Subarray Sum Equals K Using Hash Map in DSA Rust - Time & Space Complexity
We want to understand how fast the algorithm finds subarrays that add up to a target sum.
How does the time needed grow as the input array gets bigger?
Analyze the time complexity of the following code snippet.
fn subarray_sum(nums: &[i32], k: i32) -> i32 {
use std::collections::HashMap;
let mut count = 0;
let mut sum = 0;
let mut map = HashMap::new();
map.insert(0, 1);
for &num in nums {
sum += num;
if let Some(&c) = map.get(&(sum - k)) {
count += c;
}
*map.entry(sum).or_insert(0) += 1;
}
count
}
This code counts how many continuous parts of the array add up exactly to k using a hash map.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: One loop through the array elements.
- How many times: Exactly once for each element in the input array.
Each element is processed once, and hash map lookups and inserts happen in constant time on average.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 loop steps + 10 hash map operations |
| 100 | About 100 loop steps + 100 hash map operations |
| 1000 | About 1000 loop steps + 1000 hash map operations |
Pattern observation: The work grows roughly in a straight line as input size grows.
Time Complexity: O(n)
This means the time needed grows directly with the number of elements in the array.
[X] Wrong: "Because of the nested hash map operations, the time is O(n²)."
[OK] Correct: Each hash map operation is on average constant time, so they do not multiply the loop steps.
Understanding this pattern helps you solve many problems where you track sums or counts efficiently.
"What if we replaced the hash map with a simple array for counting sums? How would the time complexity change?"
Practice
Subarray Sum Equals K problem?Solution
Step 1: Understand the problem requirement
The problem requires finding subarrays whose sums equal a target valuek. Using a hash map helps track cumulative sums efficiently.Step 2: Role of hash map in the solution
The hash map stores cumulative sums as keys and their counts as values. This allows quick checking if a previous sum exists that forms a subarray summing tok.Final Answer:
To store cumulative sums and their frequencies for quick lookup -> Option AQuick Check:
Hash map stores sums = A [OK]
- Thinking hash map stores individual elements only
- Using hash map to sort elements
- Ignoring cumulative sums concept
Solution
Step 1: Identify correct HashMap initialization syntax in Rust
Rust requires importing and initializing a mutable HashMap withstd::collections::HashMap::new()andmutif we want to modify it.Step 2: Check each option
let mut map = std::collections::HashMap::new(); uses correct syntax withmutand full path. let map = HashMap::new(); missesmut. let mut map = HashMap(); uses wrong constructor syntax. let map = std::collections::HashMap; is incomplete.Final Answer:
let mut map = std::collections::HashMap::new(); -> Option BQuick Check:
Correct Rust HashMap init = D [OK]
- Forgetting mut for mutable map
- Using wrong constructor syntax
- Omitting std::collections prefix
use std::collections::HashMap;
fn subarray_sum(nums: Vec<i32>, k: i32) -> i32 {
let mut count = 0;
let mut sum = 0;
let mut map = HashMap::new();
map.insert(0, 1);
for num in nums {
sum += num;
if let Some(&c) = map.get(&(sum - k)) {
count += c;
}
*map.entry(sum).or_insert(0) += 1;
}
count
}
fn main() {
let nums = vec![1, 2, 1, 2, 1];
let k = 3;
println!("{}", subarray_sum(nums, k));
}Solution
Step 1: Trace cumulative sums and map updates
nums = [1,2,1,2,1], k=3 - sum=1, map={0:1,1:1}, count=0 - sum=3, map has (3-3)=0 count=1, count=1, map={0:1,1:1,3:1} - sum=4, map has (4-3)=1 count=1, count=2, map={0:1,1:1,3:1,4:1} - sum=6, map has (6-3)=3 count=1, count=3, map={0:1,1:1,3:1,4:1,6:1} - sum=7, map has (7-3)=4 count=1, count=4, map={0:1,1:1,3:1,4:1,6:1,7:1}Step 2: Calculate final count of subarrays
Total count of subarrays summing to 3 is 4.Final Answer:
4 -> Option DQuick Check:
Count of subarrays = 4 [OK]
- Not initializing map with (0,1)
- Incorrectly updating count
- Confusing sum and index
fn subarray_sum(nums: Vec<i32>, k: i32) -> i32 {
let mut count = 0;
let mut sum = 0;
let mut map = std::collections::HashMap::new();
for num in nums {
sum += num;
if let Some(&c) = map.get(&(sum - k)) {
count += c;
}
map.insert(sum, 1);
}
count
}Solution
Step 1: Identify problem with map insertion
Usingmap.insert(sum, 1)overwrites previous counts, losing frequency data needed for correct counting.Step 2: Correct way to update map counts
Usemap.entry(sum).or_insert(0) += 1to increment count if sum exists or insert 0 then increment, preserving frequencies.Final Answer:
Change map.insert(sum, 1) to map.entry(sum).or_insert(0) += 1 -> Option AQuick Check:
Use entry API to update counts [OK]
- Overwriting counts with insert instead of incrementing
- Not initializing map with (0,1)
- Ignoring frequency updates
nums = [3, 4, 7, 2, -3, 1, 4, 2] and k = 7, how many subarrays sum to k? Use the hash map approach to find the answer.Solution
Step 1: Calculate cumulative sums and track counts
nums = [3,4,7,2,-3,1,4,2], k=7 - sum=3, map={0:1,3:1}, count=0 - sum=7, map has (7-7)=0 count=1, count=1, map={0:1,3:1,7:1} - sum=14, map has (14-7)=7 count=1, count=2, map={0:1,3:1,7:1,14:1} - sum=16, map has (16-7)=9 no, count=2, map={0:1,3:1,7:1,14:1,16:1} - sum=13, map has (13-7)=6 no, count=2, map={0:1,3:1,7:1,14:1,16:1,13:1} - sum=14, map has (14-7)=7 count=1, count=3, map={0:1,3:1,7:1,14:2,16:1,13:1} - sum=18, map has (18-7)=11 no, count=3, map={0:1,3:1,7:1,14:2,16:1,13:1,18:1} - sum=20, map has (20-7)=13 count=1, count=4, map={0:1,3:1,7:1,14:2,16:1,13:1,18:1,20:1}Step 2: Count subarrays carefully including duplicates
The trace shows four increments corresponding to the four subarrays summing to 7: [3,4], [7], [7,2,-3,1], [1,4,2]. Total count is 4.Final Answer:
4 -> Option CQuick Check:
Count subarrays with sum k = 4 [OK]
- Not counting repeated cumulative sums correctly
- Missing negative numbers effect
- Forgetting to initialize map with (0,1)
Ready to prove it?
Pass the test and this pattern moves unknown
