Skip to content

Commit d502b21

Browse files
committed
Add problem 1932: Merge BSTs to Create Single BST
1 parent b2fc03d commit d502b21

File tree

3 files changed

+160
-0
lines changed

3 files changed

+160
-0
lines changed

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1435,6 +1435,7 @@ pub mod problem_1926_nearest_exit_from_entrance_in_maze;
14351435
pub mod problem_1927_sum_game;
14361436
pub mod problem_1929_concatenation_of_array;
14371437
pub mod problem_1930_unique_length_3_palindromic_subsequences;
1438+
pub mod problem_1932_merge_bsts_to_create_single_bst;
14381439
pub mod problem_1935_maximum_number_of_words_you_can_type;
14391440
pub mod problem_1936_add_minimum_number_of_rungs;
14401441
pub mod problem_1937_maximum_number_of_points_with_cost;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
use crate::data_structures::TreeNode;
2+
3+
pub struct Solution;
4+
5+
// ------------------------------------------------------ snip ------------------------------------------------------ //
6+
7+
use std::cell::RefCell;
8+
use std::collections::{HashMap, HashSet, VecDeque};
9+
use std::mem;
10+
use std::rc::Rc;
11+
12+
impl Solution {
13+
fn validate_binary_tree_option(prev: i32, node: &Option<Rc<RefCell<TreeNode>>>) -> Option<i32> {
14+
node.as_ref()
15+
.map_or(Some(prev), |node| Self::validate_binary_tree(prev, node))
16+
}
17+
18+
fn validate_binary_tree(mut prev: i32, node: &Rc<RefCell<TreeNode>>) -> Option<i32> {
19+
let node = node.borrow();
20+
let node = &*node;
21+
22+
prev = Self::validate_binary_tree_option(prev, &node.left)?;
23+
24+
if prev < node.val {
25+
Self::validate_binary_tree_option(node.val, &node.right)
26+
} else {
27+
None
28+
}
29+
}
30+
31+
pub fn can_merge(trees: Vec<Option<Rc<RefCell<TreeNode>>>>) -> Option<Rc<RefCell<TreeNode>>> {
32+
let trees = trees.into_iter().flatten().collect::<Vec<_>>();
33+
let mut nodes = HashMap::new();
34+
let mut non_roots = HashSet::new();
35+
36+
for tree in &trees {
37+
let tree_holder = tree.borrow();
38+
let tree_ref = &*tree_holder;
39+
40+
for child in [&tree_ref.left, &tree_ref.right].into_iter().flatten() {
41+
if !non_roots.insert(child.borrow().val) {
42+
return None;
43+
}
44+
}
45+
46+
let tree_val = tree_ref.val;
47+
48+
drop(tree_holder);
49+
50+
nodes.insert(tree_val, Rc::clone(tree));
51+
}
52+
53+
nodes
54+
.keys()
55+
.copied()
56+
.find(|key| !non_roots.contains(key))
57+
.and_then(|root_val| {
58+
let root = nodes.remove(&root_val).unwrap();
59+
let mut queue = VecDeque::from([Rc::clone(&root)]);
60+
61+
loop {
62+
for _ in 0..queue.len() {
63+
let node = queue.pop_front().unwrap();
64+
let mut node = node.borrow_mut();
65+
let node = &mut *node;
66+
67+
for child in [&mut node.left, &mut node.right].into_iter().flatten() {
68+
let child_val = child.borrow().val;
69+
70+
if let Some(real_child) = nodes.remove(&child_val) {
71+
drop(mem::replace(child, Rc::clone(&real_child)));
72+
queue.push_back(real_child);
73+
}
74+
}
75+
}
76+
77+
if queue.is_empty() {
78+
break;
79+
}
80+
}
81+
82+
if !nodes.is_empty() {
83+
return None;
84+
}
85+
86+
Self::validate_binary_tree(i32::MIN, &root).map(|_| root)
87+
})
88+
}
89+
}
90+
91+
// ------------------------------------------------------ snip ------------------------------------------------------ //
92+
93+
impl super::Solution for Solution {
94+
fn can_merge(trees: Vec<Option<Rc<RefCell<TreeNode>>>>) -> Option<Rc<RefCell<TreeNode>>> {
95+
Self::can_merge(trees)
96+
}
97+
}
98+
99+
#[cfg(test)]
100+
mod tests {
101+
#[test]
102+
fn test_solution() {
103+
super::super::tests::run::<super::Solution>();
104+
}
105+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use crate::data_structures::TreeNode;
2+
use std::cell::RefCell;
3+
use std::rc::Rc;
4+
5+
pub mod bfs;
6+
7+
pub trait Solution {
8+
fn can_merge(trees: Vec<Option<Rc<RefCell<TreeNode>>>>) -> Option<Rc<RefCell<TreeNode>>>;
9+
}
10+
11+
#[cfg(test)]
12+
mod tests {
13+
use super::Solution;
14+
use crate::test_utilities;
15+
16+
pub fn run<S: Solution>() {
17+
let test_cases = [
18+
(
19+
&[
20+
&[Some(2), Some(1)] as &[_],
21+
&[Some(3), Some(2), Some(5)],
22+
&[Some(5), Some(4)],
23+
] as &[&[_]],
24+
&[Some(3), Some(2), Some(5), Some(1), None, Some(4)] as &[_],
25+
),
26+
(&[&[Some(5), Some(3), Some(8)], &[Some(3), Some(2), Some(6)]], &[]),
27+
(&[&[Some(5), Some(4)], &[Some(3)]], &[]),
28+
(
29+
&[
30+
&[Some(4), Some(1)],
31+
&[Some(1), None, Some(2)],
32+
&[Some(2), None, Some(3)],
33+
],
34+
&[Some(4), Some(1), None, None, Some(2), None, Some(3)],
35+
),
36+
(
37+
&[&[Some(1), None, Some(3)], &[Some(3), Some(1)], &[Some(4), Some(2)]],
38+
&[],
39+
),
40+
];
41+
42+
for (trees, expected) in test_cases {
43+
assert_eq!(
44+
S::can_merge(
45+
trees
46+
.iter()
47+
.map(|tree| test_utilities::make_tree(tree.iter().copied()))
48+
.collect(),
49+
),
50+
test_utilities::make_tree(expected.iter().copied()),
51+
);
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)