From d8cabdbb041093bcdf3f92c87ce39c7d64d83999 Mon Sep 17 00:00:00 2001 From: EFanZh Date: Fri, 9 Feb 2024 13:09:56 +0800 Subject: [PATCH] Add problem 1865: Finding Pairs With a Certain Sum --- src/lib.rs | 1 + .../hash_map.rs | 79 +++++++++++++++++++ .../mod.rs | 43 ++++++++++ 3 files changed, 123 insertions(+) create mode 100644 src/problem_1865_finding_pairs_with_a_certain_sum/hash_map.rs create mode 100644 src/problem_1865_finding_pairs_with_a_certain_sum/mod.rs diff --git a/src/lib.rs b/src/lib.rs index deb29adb..49670517 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1359,6 +1359,7 @@ pub mod problem_1859_sorting_the_sentence; pub mod problem_1860_incremental_memory_leak; pub mod problem_1861_rotating_the_box; pub mod problem_1864_minimum_number_of_swaps_to_make_the_binary_string_alternating; +pub mod problem_1865_finding_pairs_with_a_certain_sum; pub mod problem_1869_longer_contiguous_segments_of_ones_than_zeros; pub mod problem_1876_substrings_of_size_three_with_distinct_characters; pub mod problem_1877_minimize_maximum_pair_sum_in_array; diff --git a/src/problem_1865_finding_pairs_with_a_certain_sum/hash_map.rs b/src/problem_1865_finding_pairs_with_a_certain_sum/hash_map.rs new file mode 100644 index 00000000..e71d4611 --- /dev/null +++ b/src/problem_1865_finding_pairs_with_a_certain_sum/hash_map.rs @@ -0,0 +1,79 @@ +// ------------------------------------------------------ snip ------------------------------------------------------ // + +use std::collections::HashMap; +use std::convert; + +pub struct FindSumPairs { + counts_1: HashMap, + counts_2: HashMap, + nums2: Vec, +} + +impl FindSumPairs { + fn count_nums(nums: &[i32]) -> HashMap { + let mut result = HashMap::with_capacity(nums.len()); + + for &num in nums { + result.entry(num).and_modify(|count| *count += 1).or_insert(1); + } + + result + } + + fn new(nums1: Vec, nums2: Vec) -> Self { + let counts_1 = Self::count_nums(&convert::identity(nums1)); + let counts_2 = Self::count_nums(&nums2); + + Self { + counts_1, + counts_2, + nums2, + } + } + + fn add(&mut self, index: i32, val: i32) { + let slot = &mut self.nums2[index as u32 as usize]; + + self.counts_2.entry(*slot).and_modify(|count| *count -= 1); + + *slot += val; + + self.counts_2.entry(*slot).and_modify(|count| *count += 1).or_insert(1); + } + + fn count(&self, tot: i32) -> i32 { + let mut result = 0; + + for (num_1, count_1) in &self.counts_1 { + if let Some(count_2) = self.counts_2.get(&(tot - num_1)) { + result += count_1 * count_2; + } + } + + result + } +} + +// ------------------------------------------------------ snip ------------------------------------------------------ // + +impl super::FindSumPairs for FindSumPairs { + fn new(nums1: Vec, nums2: Vec) -> Self { + Self::new(nums1, nums2) + } + + fn add(&mut self, index: i32, val: i32) { + self.add(index, val); + } + + fn count(&self, tot: i32) -> i32 { + self.count(tot) + } +} + +#[cfg(test)] +mod tests { + #[test] + fn test_solution() { + super::super::tests::run::(); + } +} diff --git a/src/problem_1865_finding_pairs_with_a_certain_sum/mod.rs b/src/problem_1865_finding_pairs_with_a_certain_sum/mod.rs new file mode 100644 index 00000000..8def149f --- /dev/null +++ b/src/problem_1865_finding_pairs_with_a_certain_sum/mod.rs @@ -0,0 +1,43 @@ +pub mod hash_map; + +pub trait FindSumPairs { + fn new(nums1: Vec, nums2: Vec) -> Self; + fn add(&mut self, index: i32, val: i32); + fn count(&self, tot: i32) -> i32; +} + +#[cfg(test)] +mod tests { + use super::FindSumPairs; + + enum Operation { + Add(i32, i32), + Count(i32, i32), + } + + pub fn run() { + let test_cases = [( + (&[1, 1, 2, 2, 2, 3] as &[_], &[1, 4, 5, 2, 5, 4] as &[_]), + &[ + Operation::Count(7, 8), + Operation::Add(3, 2), + Operation::Count(8, 2), + Operation::Count(4, 1), + Operation::Add(0, 1), + Operation::Add(1, 1), + Operation::Count(7, 11), + ] as &[_], + )]; + + for ((nums1, nums2), operations) in test_cases { + let mut find_sum_pairs = F::new(nums1.to_vec(), nums2.to_vec()); + + for operation in operations { + match *operation { + Operation::Add(index, val) => find_sum_pairs.add(index, val), + Operation::Count(tot, expected) => assert_eq!(find_sum_pairs.count(tot), expected), + } + } + } + } +}