Skip to content

Commit 4ef4879

Browse files
committed
Added AdjacencyGraph and Minimum Height Trees
1 parent 2bd295c commit 4ef4879

File tree

3 files changed

+154
-0
lines changed

3 files changed

+154
-0
lines changed

src/adjacency_graph.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
use std::collections::HashMap;
2+
use std::collections::HashSet;
3+
4+
#[derive(Clone, Debug, PartialEq)]
5+
pub struct AdjacencyGraph {
6+
neighbors: HashMap<i32, HashSet<i32>>,
7+
}
8+
9+
impl AdjacencyGraph {
10+
11+
pub fn new() -> Self {
12+
Self { neighbors: HashMap::new() }
13+
}
14+
15+
pub fn from_neighbors(neighbors: &HashMap<i32, HashSet<i32>>) -> Self {
16+
Self { neighbors: neighbors.clone() }
17+
}
18+
19+
pub fn from_vec(edges: &Vec<Vec<i32>>) -> Self {
20+
let mut result = Self::new();
21+
for edge in edges {
22+
result.add_edge(edge[0], edge[1]);
23+
}
24+
result
25+
}
26+
27+
pub fn add_edge(&mut self, x: i32, y: i32) {
28+
self.neighbors
29+
.entry(x)
30+
.or_insert(HashSet::new())
31+
.insert(y);
32+
self.neighbors
33+
.entry(y)
34+
.or_insert(HashSet::new())
35+
.insert(x);
36+
}
37+
38+
pub fn remove_edge(&mut self, x: i32, y: i32) {
39+
self.neighbors
40+
.entry(x)
41+
.and_modify(|s| { s.remove(&y); });
42+
self.neighbors
43+
.entry(y)
44+
.and_modify(|s| { s.remove(&x); });
45+
}
46+
47+
pub fn is_leaf(&self, x: i32) -> bool {
48+
self.neighbors
49+
.get(&x)
50+
.map(|s| s.len() == 1)
51+
.unwrap_or_default()
52+
}
53+
54+
pub fn find_leaves(&self) -> Vec<i32> {
55+
self.neighbors
56+
.iter()
57+
.filter(|(_, v)| v.len() == 1)
58+
.map(|(k, _)| k)
59+
.copied()
60+
.collect()
61+
}
62+
63+
pub fn find_leaf_neighbor(&self, x: i32) -> i32 {
64+
self.neighbors
65+
.get(&x)
66+
.and_then(|s| s.iter().next())
67+
.copied()
68+
.unwrap_or(-1)
69+
}
70+
71+
pub fn find_centroids(&self) -> Vec<i32> {
72+
if self.neighbors.len() <= 2 {
73+
self.neighbors.keys().copied().collect()
74+
} else {
75+
let mut cloned = self.clone();
76+
77+
let mut leaves = cloned.find_leaves();
78+
let mut left = cloned.neighbors.len();
79+
while left > 2 {
80+
let mut next_leaves = Vec::new();
81+
left -= leaves.len();
82+
for &leaf in &leaves {
83+
let neighbor = cloned.find_leaf_neighbor(leaf);
84+
cloned.remove_edge(leaf, neighbor);
85+
if cloned.is_leaf(neighbor) {
86+
next_leaves.push(neighbor);
87+
}
88+
}
89+
leaves = next_leaves;
90+
}
91+
92+
leaves
93+
}
94+
}
95+
96+
}

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub mod stack;
1212
pub mod tree_node;
1313
pub mod tree_node_additions;
1414
pub mod vec_additions;
15+
pub mod adjacency_graph;
1516

1617
pub mod two_sum; // 1
1718
pub mod add_two_numbers; // 2
@@ -116,6 +117,8 @@ pub mod serialize_and_deserialize_binary_tree; // 297
116117

117118
pub mod longest_increasing_subsequence; // 300
118119

120+
pub mod minimum_height_trees; // 310
121+
119122
pub mod shortest_distance_from_all_buildings; // 317
120123

121124
pub mod bulb_switcher; // 319

src/minimum_height_trees.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use crate::adjacency_graph::AdjacencyGraph;
2+
use std::collections::HashMap;
3+
use std::collections::HashSet;
4+
use std::collections::VecDeque;
5+
6+
/// A tree is an undirected graph in which any two vertices are connected by
7+
/// exactly one path. In other words, any connected graph without simple cycles
8+
/// is a tree.
9+
///
10+
/// Given a tree of `n` nodes labelled from `0` to `n - 1`, and an array of
11+
/// `n - 1` `edges` where `edges[i] = [ai, bi]` indicates that there is an
12+
/// undirected edge between the two nodes `ai` and `bi` in the tree, you can
13+
/// choose any node of the tree as the root. When you select a node `x` as the
14+
/// root, the result tree has height `h`. Among all possible rooted trees,
15+
/// those with minimum height (i.e. `min(h)`) are called minimum height trees
16+
/// (MHTs).
17+
///
18+
/// Return a list of all MHT's root labels. You can return the answer in any
19+
/// order.
20+
///
21+
/// The height of a rooted tree is the number of edges on the longest downward
22+
/// path between the root and a leaf.
23+
struct Solution;
24+
25+
impl Solution {
26+
27+
pub fn find_min_height_tree(_n: i32, edges: Vec<Vec<i32>>) -> Vec<i32> {
28+
let graph = AdjacencyGraph::from_vec(&edges);
29+
graph.find_centroids()
30+
}
31+
32+
}
33+
34+
#[cfg(test)]
35+
mod tests {
36+
use super::Solution;
37+
38+
#[test]
39+
fn example_1() {
40+
let n = 4;
41+
let edges = vec![vec![1,0], vec![1,2], vec![1,3]];
42+
let result = Solution::find_min_height_tree(n, edges);
43+
assert_eq!(result, vec![1]);
44+
}
45+
46+
#[test]
47+
fn example_2() {
48+
let n = 6;
49+
let edges = vec![vec![3,0], vec![3,1], vec![3,2], vec![3,4], vec![5,4]];
50+
let mut result = Solution::find_min_height_tree(n, edges);
51+
result.sort();
52+
assert_eq!(result, vec![3,4]);
53+
}
54+
55+
}

0 commit comments

Comments
 (0)