Skip to content

Commit 2140b34

Browse files
authored
Create merge-bsts-to-create-single-bst.cpp
1 parent 937e511 commit 2140b34

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Time: O(n)
2+
// Space: O(n)
3+
4+
class Solution {
5+
public:
6+
TreeNode* canMerge(vector<TreeNode*>& trees) {
7+
unordered_set<int> leaf_vals_set;
8+
unordered_map<int, TreeNode*> val_to_root;
9+
find_leaves_and_roots(trees, &leaf_vals_set, &val_to_root);
10+
const auto& root = find_root(trees, leaf_vals_set, val_to_root);
11+
return merge_bsts(root, leaf_vals_set, &val_to_root);
12+
}
13+
14+
private:
15+
void find_leaves_and_roots(
16+
const vector<TreeNode*>& trees,
17+
unordered_set<int> *leaf_vals_set,
18+
unordered_map<int, TreeNode*> *val_to_root) {
19+
20+
for (const auto& root : trees) {
21+
(*val_to_root)[root->val] = root;
22+
vector<TreeNode*> q = {root};
23+
while (!empty(q)) {
24+
vector<TreeNode*> new_q;
25+
for (const auto& node : q) {
26+
if (!node->left && !node->right) {
27+
if (node != root) {
28+
leaf_vals_set->emplace(node->val);
29+
}
30+
continue;
31+
}
32+
if (node->left) {
33+
new_q.emplace_back(node->left);
34+
}
35+
if (node->right) {
36+
new_q.emplace_back(node->right);
37+
}
38+
}
39+
q = move(new_q);
40+
}
41+
}
42+
}
43+
44+
TreeNode* find_root(
45+
const vector<TreeNode*>& trees,
46+
const unordered_set<int>& leaf_vals_set,
47+
const unordered_map<int, TreeNode*>& val_to_root) {
48+
49+
TreeNode *root = nullptr;
50+
for (const auto& node : trees) {
51+
if (leaf_vals_set.count(node->val)) {
52+
continue;
53+
}
54+
if (root) { // multiple roots
55+
return nullptr;
56+
}
57+
root = node;
58+
}
59+
return root;
60+
}
61+
62+
TreeNode* merge_bsts(
63+
TreeNode *root,
64+
const unordered_set<int>& leaf_vals_set,
65+
unordered_map<int, TreeNode*> *val_to_root) {
66+
67+
if (!root) {
68+
return nullptr;
69+
}
70+
val_to_root->erase(root->val);
71+
vector<tuple<TreeNode*, int, int>> q = {{root, numeric_limits<int>::min(), numeric_limits<int>::max()}};
72+
while (!empty(q)) {
73+
vector<tuple<TreeNode*, int, int>> new_q;
74+
for (const auto& [node, left, right] : q) {
75+
if (!(left < node->val && node->val < right)) {
76+
return nullptr;
77+
}
78+
if (node->left) {
79+
if (leaf_vals_set.count(node->left->val) && val_to_root->count(node->left->val)) {
80+
node->left = (*val_to_root)[node->left->val];
81+
val_to_root->erase(node->left->val);
82+
}
83+
new_q.emplace_back(node->left, left, node->val);
84+
}
85+
if (node->right) {
86+
if (leaf_vals_set.count(node->right->val) && val_to_root->count(node->right->val)) {
87+
node->right = (*val_to_root)[node->right->val];
88+
val_to_root->erase(node->right->val);
89+
}
90+
new_q.emplace_back(node->right, node->val, right);
91+
}
92+
}
93+
q = move(new_q);
94+
}
95+
return empty(*val_to_root) ? root : nullptr;
96+
}
97+
};

0 commit comments

Comments
 (0)