Skip to main content
Back to problems
#1932
Hard Algorithms

Merge bsts to create single bst

Array Hash Table Tree Depth-First Search Binary Search Tree Binary Tree
38.0% acceptance
Feb 25, 2026
657
47
You are given n BST (binary search tree) root nodes for n separate BSTs stored in an array trees (0-indexed). Each BST in trees has at most 3 nodes, and no two roots have the same value. In one operation, you can: Select two distinct indices i and j such that the value stored at one of the leaves of trees[i] is equal to the root value of trees[j]. Replace the leaf node in trees[i] with trees[j]. Remove trees[j] from trees. Return the root of the resulting BST if it is possible to form a valid BST after performing n - 1 operations, or null if it is impossible to create a valid BST. A BST (binary search tree) is a binary tree where each node satisfies the following property: Every node in the node's left subtree has a value strictly less than the node's value. Every node in the node's right subtree has a value strictly greater than the node's value. A leaf is a node that has no children.

Solution

Rust
Time O(n)
Space O(n)
LeetCode
solution.rs
use std::rc::Rc;
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};

impl Solution {
  pub fn can_merge(trees: Vec<Option<Rc<RefCell<TreeNode>>>>) -> Option<Rc<RefCell<TreeNode>>> {
    let mut root_map: HashMap<i32, Rc<RefCell<TreeNode>>> = HashMap::new();
    let mut root_vals: HashSet<i32> = HashSet::new();
    let mut leaf_count: HashMap<i32, i32> = HashMap::new();

    for tree in &trees {
      if let Some(node) = tree {
        let val = node.borrow().val;
        root_vals.insert(val);
        root_map.insert(val, Rc::clone(node));
      }
    }

    for tree in &trees {
      if let Some(node) = tree {
        let b = node.borrow();
        if let Some(ref left) = b.left {
          *leaf_count.entry(left.borrow().val).or_insert(0) += 1;
        }
        if let Some(ref right) = b.right {
          *leaf_count.entry(right.borrow().val).or_insert(0) += 1;
        }
      }
    }

    // Find the root: a root node whose value is not a leaf of any other tree
    let mut main_root = None;
    for &val in &root_vals {
      if !leaf_count.contains_key(&val) {
        if main_root.is_some() {
          return None; // multiple roots
        }
        main_root = Some(val);
      }
    }

    let main_root = main_root?;
    let root = root_map.remove(&main_root)?;

    // Build tree by merging
    Self::merge(&root, &mut root_map);

    // All trees should have been used
    if !root_map.is_empty() {
      return None;
    }

    // Validate BST
    if Self::is_valid_bst(&Some(Rc::clone(&root)), i64::MIN, i64::MAX) {
      Some(root)
    } else {
      None
    }
  }

  fn merge(node: &Rc<RefCell<TreeNode>>, root_map: &mut HashMap<i32, Rc<RefCell<TreeNode>>>) {
    let mut b = node.borrow_mut();

    // Try to merge left child
    if let Some(ref left) = b.left {
      let lv = left.borrow().val;
      if left.borrow().left.is_none() && left.borrow().right.is_none() {
        if let Some(subtree) = root_map.remove(&lv) {
          b.left = Some(Rc::clone(&subtree));
          Self::merge(&subtree, root_map);
        }
      }
    }

    // Try to merge right child
    if let Some(ref right) = b.right {
      let rv = right.borrow().val;
      if right.borrow().left.is_none() && right.borrow().right.is_none() {
        if let Some(subtree) = root_map.remove(&rv) {
          b.right = Some(Rc::clone(&subtree));
          Self::merge(&subtree, root_map);
        }
      }
    }
  }

  fn is_valid_bst(node: &Option<Rc<RefCell<TreeNode>>>, min: i64, max: i64) -> bool {
    match node {
      None => true,
      Some(n) => {
        let b = n.borrow();
        let val = b.val as i64;
        if val <= min || val >= max {
          return false;
        }
        Self::is_valid_bst(&b.left, min, val) && Self::is_valid_bst(&b.right, val, max)
      }
    }
  }
}