Skip to content

Commit b8a3ec7

Browse files
rust: 236. Lowest Common Ancestor of a Binary Tree
1 parent 78650cf commit b8a3ec7

File tree

1 file changed

+151
-0
lines changed
  • golang/algorithms/others/lowest_common_ancestor_of_a_binary_tree

1 file changed

+151
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
use std::{cell::RefCell, collections::HashSet, rc::Rc};
2+
3+
#[derive(Debug, PartialEq, Eq)]
4+
pub struct TreeNode {
5+
pub val: i32,
6+
pub left: Option<Rc<RefCell<TreeNode>>>,
7+
pub right: Option<Rc<RefCell<TreeNode>>>,
8+
}
9+
10+
#[derive(PartialEq, Eq)]
11+
struct HashableTreeNode(Rc<RefCell<TreeNode>>);
12+
13+
impl std::hash::Hash for HashableTreeNode {
14+
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
15+
self.0.borrow().val.hash(state);
16+
}
17+
}
18+
19+
impl TreeNode {
20+
#[inline]
21+
pub fn new(val: i32) -> Self {
22+
TreeNode {
23+
val,
24+
left: None,
25+
right: None,
26+
}
27+
}
28+
}
29+
30+
pub fn lowest_common_ancestor(
31+
root: Option<Rc<RefCell<TreeNode>>>,
32+
p: Option<Rc<RefCell<TreeNode>>>,
33+
q: Option<Rc<RefCell<TreeNode>>>,
34+
) -> Option<Rc<RefCell<TreeNode>>> {
35+
let ancestors_p = find_ancestors(root.clone(), p.unwrap().borrow().val, Vec::new()).unwrap();
36+
let ancestors_q = find_ancestors(root, q.unwrap().borrow().val, Vec::new()).unwrap();
37+
38+
let ancestors_p: HashSet<_> = ancestors_p.into_iter().map(HashableTreeNode).collect();
39+
40+
for ancestor in ancestors_q.into_iter().rev() {
41+
if ancestors_p.contains(&HashableTreeNode(Rc::clone(&ancestor))) {
42+
return Some(ancestor);
43+
}
44+
}
45+
46+
None
47+
}
48+
49+
pub fn find_ancestors(
50+
root: Option<Rc<RefCell<TreeNode>>>,
51+
v: i32,
52+
mut ancestors: Vec<Rc<RefCell<TreeNode>>>,
53+
) -> Option<Vec<Rc<RefCell<TreeNode>>>> {
54+
match root {
55+
None => None,
56+
Some(node) => {
57+
ancestors.push(Rc::clone(&node));
58+
if node.borrow().val == v {
59+
return Some(ancestors);
60+
}
61+
62+
if let Some(ancestors) =
63+
find_ancestors(node.borrow().left.clone(), v, ancestors.clone())
64+
{
65+
return Some(ancestors);
66+
}
67+
68+
find_ancestors(node.borrow().right.clone(), v, ancestors)
69+
}
70+
}
71+
}
72+
73+
fn main() {}
74+
75+
#[cfg(test)]
76+
mod tests {
77+
use super::*;
78+
79+
#[test]
80+
fn test_lowest_common_ancestor() {
81+
let tree_1 = Some(Rc::new(RefCell::new(TreeNode {
82+
val: 3,
83+
left: Some(Rc::new(RefCell::new(TreeNode {
84+
val: 5,
85+
left: Some(Rc::new(RefCell::new(TreeNode {
86+
val: 6,
87+
left: None,
88+
right: None,
89+
}))),
90+
right: Some(Rc::new(RefCell::new(TreeNode {
91+
val: 2,
92+
left: Some(Rc::new(RefCell::new(TreeNode {
93+
val: 7,
94+
left: None,
95+
right: None,
96+
}))),
97+
right: Some(Rc::new(RefCell::new(TreeNode {
98+
val: 4,
99+
left: None,
100+
right: None,
101+
}))),
102+
}))),
103+
}))),
104+
right: Some(Rc::new(RefCell::new(TreeNode {
105+
val: 1,
106+
left: Some(Rc::new(RefCell::new(TreeNode {
107+
val: 0,
108+
left: None,
109+
right: None,
110+
}))),
111+
right: Some(Rc::new(RefCell::new(TreeNode {
112+
val: 8,
113+
left: None,
114+
right: None,
115+
}))),
116+
}))),
117+
})));
118+
let result = lowest_common_ancestor(
119+
tree_1.clone(),
120+
tree_1.clone().and_then(|tree| tree.borrow().left.clone()),
121+
tree_1.clone().and_then(|tree| tree.borrow().right.clone()),
122+
);
123+
assert_eq!(3, result.unwrap().borrow().val);
124+
125+
let result = lowest_common_ancestor(
126+
tree_1.clone(),
127+
tree_1.clone().and_then(|tree| tree.borrow().left.clone()),
128+
tree_1
129+
.and_then(|tree| tree.borrow().left.clone())
130+
.and_then(|node| node.borrow().right.clone())
131+
.and_then(|node| node.borrow().right.clone()),
132+
);
133+
assert_eq!(5, result.unwrap().borrow().val);
134+
135+
let tree_2 = Some(Rc::new(RefCell::new(TreeNode {
136+
val: 1,
137+
left: Some(Rc::new(RefCell::new(TreeNode {
138+
val: 2,
139+
left: None,
140+
right: None,
141+
}))),
142+
right: None,
143+
})));
144+
let result = lowest_common_ancestor(
145+
tree_2.clone(),
146+
tree_2.clone(),
147+
tree_2.and_then(|tree| tree.borrow().left.clone()),
148+
);
149+
assert_eq!(1, result.unwrap().borrow().val);
150+
}
151+
}

0 commit comments

Comments
 (0)