|
| 1 | +use std::collections::HashMap; |
| 2 | + |
| 3 | +/// Counts the number of contiguous subarrays that sum to exactly k. |
| 4 | +/// |
| 5 | +/// # Parameters |
| 6 | +/// |
| 7 | +/// - `nums`: A slice of integers |
| 8 | +/// - `k`: The target sum |
| 9 | +/// |
| 10 | +/// # Returns |
| 11 | +/// |
| 12 | +/// The number of contiguous subarrays with sum equal to k. |
| 13 | +/// |
| 14 | +/// # Complexity |
| 15 | +/// |
| 16 | +/// - Time: O(n) |
| 17 | +/// - Space: O(n) |
| 18 | +
|
| 19 | +pub fn subarray_sum_equals_k(nums: &[i32], k: i32) -> i32 { |
| 20 | + let mut prefix_sum_count: HashMap<i64, i32> = HashMap::new(); |
| 21 | + prefix_sum_count.insert(0, 1); |
| 22 | + |
| 23 | + let mut prefix_sum: i64 = 0; |
| 24 | + let mut count = 0; |
| 25 | + |
| 26 | + for &num in nums { |
| 27 | + prefix_sum += num as i64; |
| 28 | + let target = prefix_sum - k as i64; |
| 29 | + |
| 30 | + if let Some(&freq) = prefix_sum_count.get(&target) { |
| 31 | + count += freq; |
| 32 | + } |
| 33 | + |
| 34 | + *prefix_sum_count.entry(prefix_sum).or_insert(0) += 1; |
| 35 | + } |
| 36 | + |
| 37 | + count |
| 38 | +} |
| 39 | + |
| 40 | +#[cfg(test)] |
| 41 | +mod test { |
| 42 | + use super::*; |
| 43 | + |
| 44 | + #[test] |
| 45 | + fn test_basic() { |
| 46 | + assert_eq!(subarray_sum_equals_k(&[1, 1, 1], 2), 2); |
| 47 | + assert_eq!(subarray_sum_equals_k(&[1, 2, 3], 3), 2); |
| 48 | + } |
| 49 | + |
| 50 | + #[test] |
| 51 | + fn test_single_element() { |
| 52 | + assert_eq!(subarray_sum_equals_k(&[1], 1), 1); |
| 53 | + assert_eq!(subarray_sum_equals_k(&[1], 0), 0); |
| 54 | + } |
| 55 | + |
| 56 | + #[test] |
| 57 | + fn test_empty() { |
| 58 | + assert_eq!(subarray_sum_equals_k(&[], 0), 0); |
| 59 | + assert_eq!(subarray_sum_equals_k(&[], 5), 0); |
| 60 | + } |
| 61 | + |
| 62 | + #[test] |
| 63 | + fn test_negative_numbers() { |
| 64 | + assert_eq!(subarray_sum_equals_k(&[-1, -1, 1], 0), 1); |
| 65 | + assert_eq!(subarray_sum_equals_k(&[1, -1, 0], 0), 3); |
| 66 | + } |
| 67 | + |
| 68 | + #[test] |
| 69 | + fn test_no_match() { |
| 70 | + assert_eq!(subarray_sum_equals_k(&[1, 2, 3], 10), 0); |
| 71 | + } |
| 72 | + |
| 73 | + #[test] |
| 74 | + fn test_multiple_matches() { |
| 75 | + assert_eq!(subarray_sum_equals_k(&[1, 0, 1, 0, 1], 1), 8); |
| 76 | + } |
| 77 | +} |
0 commit comments