algos/src/two_sum.rs

78 lines
1.7 KiB
Rust

use std::collections::HashSet;
fn binary_search<T: std::cmp::PartialOrd>(
min_i: usize,
max_i: usize,
xs: &Vec<T>,
needle: T,
) -> usize {
if min_i >= max_i {
return max_i;
}
let half_i = min_i + (max_i - min_i) / 2;
if xs[half_i] == needle {
return half_i;
}
if needle < xs[half_i] {
binary_search(min_i, half_i - 1, &xs, needle)
} else {
binary_search(half_i + 1, max_i, xs, needle)
}
}
pub fn find_two_sums(xs: &mut Vec<i64>) -> usize {
let mut found: HashSet<i64> = HashSet::new();
const T_MIN: i64 = -10000;
const T_MAX: i64 = 10000;
xs.sort();
for i in 0..xs.len() {
let a: i64 = xs[i];
let b_min = T_MIN - a;
let b_max = T_MAX - a;
let i_min = binary_search(i + 1, xs.len() - 1, &xs, b_min);
let i_max = binary_search(i + 1, xs.len() - 1, &xs, b_max);
for i in i_min..(i_max + 1) {
let b = xs[i];
let t = a + b;
if T_MIN <= t && t <= T_MAX {
found.insert(t);
}
}
}
found.len()
}
// fn two_sum(t: i64, xs: &Vec<i64>, ys: &HashSet<i64>) -> bool {
// for &x in xs {
// let y = t - x;
// if x != y && ys.contains(&y) {
// return true;
// }
// }
// false
// }
// pub fn find_two_sums_naiv(xs: Vec<i64>) -> usize {
// let mut xs_min: Vec<i64> = xs.to_vec();
// xs_min.retain(|&i| i < 0);
// let mut xs_max: Vec<i64> = xs.to_vec();
// xs_max.retain(|&i| i >= 0);
// let xs_max_set: HashSet<i64> = HashSet::from_iter(xs_max);
// let mut r: usize = 0;
// for t in -10000..10001 {
// if t % 10 == 0 {
// println!("{:?}", t);
// }
// if two_sum(t, &xs_min, &xs_max_set) {
// r += 1
// }
// }
// r
// }