From 5aa7401eeddeb20495e0e191d2ba31e7bfd2855f Mon Sep 17 00:00:00 2001 From: jackfiled Date: Sun, 23 Jun 2024 11:19:08 +0800 Subject: [PATCH] 20240623 Finished --- src/problem/mod.rs | 3 +- src/problem/p399_evaluate_division.rs | 122 ++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 src/problem/p399_evaluate_division.rs diff --git a/src/problem/mod.rs b/src/problem/mod.rs index 68c2c51..e535e2a 100644 --- a/src/problem/mod.rs +++ b/src/problem/mod.rs @@ -155,4 +155,5 @@ mod p530_minimum_absolute_difference_in_bst; mod p230_kth_smallest_element_in_a_bst; mod p98_validate_binary_search_tree; mod p200_number_of_islands; -mod p130_surrounded_regions; \ No newline at end of file +mod p130_surrounded_regions; +mod p399_evaluate_division; \ No newline at end of file diff --git a/src/problem/p399_evaluate_division.rs b/src/problem/p399_evaluate_division.rs new file mode 100644 index 0000000..b6f1a40 --- /dev/null +++ b/src/problem/p399_evaluate_division.rs @@ -0,0 +1,122 @@ +/** + * [399] Evaluate Division + */ +pub struct Solution {} + + +// submission codes start here +use std::collections::HashMap; + +struct UnionFind { + parents : Vec, + weights : Vec +} + +impl UnionFind { + fn new(n: usize) -> UnionFind { + let mut parents = Vec::with_capacity(n); + let mut weights = Vec::with_capacity(n); + + for i in 0..n { + parents.push(i); + weights.push(1f64); + } + + UnionFind { + parents, + weights + } + } + + fn find(&mut self, x: usize) -> usize { + if self.parents[x] == x { + return x; + } + + let origin = self.parents[x]; + self.parents[x] = self.find(origin); + self.weights[x] *= self.weights[origin]; + self.parents[x] + } + + fn merge(&mut self, x: usize, y: usize, value: f64) { + let (x_root, y_root) = (self.find(x), self.find(y)); + + if x_root == y_root { + return; + } + + self.parents[x_root] = y_root; + self.weights[x_root] = value * self.weights[y] / self.weights[x]; + } + + fn is_connected(&mut self, x: usize, y: usize) -> f64 { + let (x_root, y_root) = (self.find(x), self.find(y)); + + if x_root == y_root { + return self.weights[x] / self.weights[y]; + } + + -1f64 + } +} + +impl Solution { + pub fn calc_equation(equations: Vec>, values: Vec, queries: Vec>) -> Vec { + let count = equations.len(); + let mut union_find = UnionFind::new(count * 2); + let mut id_map = HashMap::with_capacity(count * 2); + let mut id = 0; + + for (i, equation) in equations.iter().enumerate() { + let (x, y) = (&equation[0], &equation[1]); + + let x_id = *id_map.entry(x).or_insert_with(|| { + let inserted_id = id; + id += 1; + inserted_id + }); + + let y_id = *id_map.entry(y).or_insert_with(|| { + let inserted_id = id; + id += 1; + inserted_id + }); + + union_find.merge(x_id, y_id, values[i]); + } + + let mut result = Vec::with_capacity(queries.len()); + for query in &queries { + let (x, y) = (&query[0], &query[1]); + + let (x_id, y_id) = (id_map.get(x), id_map.get(y)); + + if x_id.is_none() || y_id.is_none() { + result.push(-1f64); + } else { + result.push(union_find.is_connected(*x_id.unwrap(),*y_id.unwrap())); + } + } + + result + } +} + +// submission codes end + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_399() { + let mut map = HashMap::new(); + let x = "a".to_owned(); + let y = "a".to_owned(); + + map.entry(&x).or_insert(1); + + assert_eq!(map.get(&y), Some(&1)); + } +}