78 lines
1.7 KiB
Rust
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
|
|
// }
|