Skip to content

Commit

Permalink
Add problem 1865: Finding Pairs With a Certain Sum
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Feb 9, 2024
1 parent 008d7e7 commit d8cabdb
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
79 changes: 79 additions & 0 deletions src/problem_1865_finding_pairs_with_a_certain_sum/hash_map.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// ------------------------------------------------------ snip ------------------------------------------------------ //

use std::collections::HashMap;
use std::convert;

pub struct FindSumPairs {
counts_1: HashMap<i32, i32>,
counts_2: HashMap<i32, i32>,
nums2: Vec<i32>,
}

impl FindSumPairs {
fn count_nums(nums: &[i32]) -> HashMap<i32, i32> {
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<i32>, nums2: Vec<i32>) -> 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<i32>, nums2: Vec<i32>) -> 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::<super::FindSumPairs>();
}
}
43 changes: 43 additions & 0 deletions src/problem_1865_finding_pairs_with_a_certain_sum/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
pub mod hash_map;

pub trait FindSumPairs {
fn new(nums1: Vec<i32>, nums2: Vec<i32>) -> 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<F: FindSumPairs>() {
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),
}
}
}
}
}

0 comments on commit d8cabdb

Please sign in to comment.