Skip to content

Instantly share code, notes, and snippets.

@ascherj
Created July 30, 2025 22:06
Show Gist options
  • Select an option

  • Save ascherj/30b3636e20fc69c9dea721de67e1e7c2 to your computer and use it in GitHub Desktop.

Select an option

Save ascherj/30b3636e20fc69c9dea721de67e1e7c2 to your computer and use it in GitHub Desktop.

πŸ§‘β€πŸ’» Interviewer Guide: Insert into a Binary Search Tree (UMPIRE Method)

https://leetcode.com/problems/insert-into-a-binary-search-tree/

πŸ“Œ Problem Statement

Given the root node of a binary search tree (BST) and a value to insert into the tree,
Return the root node of the BST after the insertion. It is guaranteed that the new value does not exist in the original BST.

Note that there may exist multiple valid ways for the insertion, as long as the tree remains a valid BST after insertion.


🧭 U β€” Understand the Problem

Interviewer Prompts & Possible Answers:

  • "Can you restate the problem in your own words?"
    β†’ "We need to insert a new value into a binary search tree while maintaining the BST property, and return the root of the modified tree."

  • "What is the BST property we need to maintain?"
    β†’ "For every node, all values in the left subtree are smaller, and all values in the right subtree are larger than the node's value."

  • "What should we return?"
    β†’ "The root node of the BST after insertion. This might be the same root or a new root if the original tree was empty."

  • "What if the tree is initially empty?"
    β†’ "We create a new node with the given value and return it as the root."

  • "The problem mentions multiple valid ways - what does that mean?"
    β†’ "Depending on where we insert, we might get different tree structures, but all should be valid BSTs. For example, we could insert as a leaf or potentially restructure the tree."

  • "Are there any constraints on the values?"
    β†’ "The value to insert doesn't already exist in the tree, and we need to maintain BST ordering."


πŸ§ͺ M β€” Match with Patterns

Interviewer Prompts & Possible Answers:

  • "What's the typical approach for BST operations?"
    β†’ "Most BST operations use the comparison property to navigate left or right, similar to binary search."

  • "Have you seen similar tree insertion problems?"
    β†’ "Yes, this is like binary search but instead of finding a value, we're finding the correct position to insert."

  • "Do you think recursion or iteration would work better?"
    β†’ "Both can work. Recursion feels natural for tree problems, but iteration with a parent pointer tracking might be clearer for insertion."

  • "What's the key insight for BST insertion?"
    β†’ "We follow the BST property to find the correct leaf position, then attach the new node there."

  • "How does this compare to searching in a BST?"
    β†’ "Very similar! We search until we reach a null position, then insert there instead of returning 'not found'."


πŸ› οΈ P β€” Plan the Solution

Interviewer Prompts & Possible Answers:

  • "Walk me through your approach for the recursive solution."
    β†’ "If the current node is null, create and return a new node. Otherwise, compare the value with current node and recursively insert into the appropriate subtree."

  • "What's your base case for recursion?"
    β†’ "When we reach a null node - that's where we insert the new node."

  • "How do you decide whether to go left or right?"
    β†’ "If the value to insert is less than the current node's value, go left. If greater, go right."

  • "What needs to be updated after insertion?"
    β†’ "We need to make sure the parent node points to the newly modified subtree."

  • "Could you outline an iterative approach?"
    β†’ "Keep track of the current node and its parent. When we reach null, we know the parent and which child (left or right) to set."

  • "What do you return from your function?"
    β†’ "The root of the tree. For recursive approach, this naturally bubbles up. For iterative, we return the original root (or new root if tree was empty)."


⌨️ I β€” Implement

Recursive Solution

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def insertIntoBST(root: TreeNode, val: int) -> TreeNode:
    # Base case: if current node is None, create new node here
    if not root:
        return TreeNode(val)
    
    # Recursive case: insert into appropriate subtree
    if val < root.val:
        root.left = insertIntoBST(root.left, val)
    else:  # val > root.val (guaranteed no duplicates)
        root.right = insertIntoBST(root.right, val)
    
    # Return the root of this subtree
    return root

Iterative Solution

def insertIntoBST(root: TreeNode, val: int) -> TreeNode:
    # Handle empty tree
    if not root:
        return TreeNode(val)
    
    # Find the correct position to insert
    current = root
    while True:
        if val < current.val:
            if current.left is None:
                current.left = TreeNode(val)
                break
            current = current.left
        else:  # val > current.val
            if current.right is None:
                current.right = TreeNode(val)
                break
            current = current.right
    
    return root

Iterative with Parent Tracking (Alternative)

def insertIntoBST(root: TreeNode, val: int) -> TreeNode:
    # Handle empty tree
    if not root:
        return TreeNode(val)
    
    # Find parent of insertion point
    current = root
    parent = None
    
    while current:
        parent = current
        if val < current.val:
            current = current.left
        else:
            current = current.right
    
    # Insert as child of parent
    new_node = TreeNode(val)
    if val < parent.val:
        parent.left = new_node
    else:
        parent.right = new_node
    
    return root

πŸ” R β€” Review

Interviewer Prompts & Possible Answers:

  • "What edge cases should we test?"
    β†’ "Empty tree, inserting into a single-node tree, inserting the smallest/largest value, inserting into a balanced vs skewed tree."

  • "How would you verify the BST property is maintained?"
    β†’ "We could do an inorder traversal and check that the result is sorted, or verify that each node satisfies the BST property."

  • "Could you trace through an example?"
    β†’ "Sure, inserting 4 into tree [4,2,7,1,3]: Since 4 == root, go right. 4 < 7, go left. 7's left is null, so insert 4 there."

  • "What about inserting into an empty tree?"
    β†’ "We create a new TreeNode(val) and return it as the new root."

Test Cases:

def test_insertIntoBST():
    # Empty tree
    result = insertIntoBST(None, 5)
    assert result.val == 5 and result.left is None and result.right is None
    
    # Single node tree
    root = TreeNode(5)
    result = insertIntoBST(root, 3)
    assert result.val == 5 and result.left.val == 3
    
    result = insertIntoBST(root, 7)  # Note: root is now modified
    assert result.val == 5 and result.right.val == 7
    
    # Complex tree
    root = TreeNode(4,
        left=TreeNode(2, TreeNode(1), TreeNode(3)),
        right=TreeNode(7)
    )
    result = insertIntoBST(root, 5)
    # Should insert 5 as left child of 7
    assert result.right.left.val == 5
    
    # Insert smallest value
    result = insertIntoBST(root, 0)
    # Should insert as left child of 1
    assert result.left.left.left.val == 0

def inorder_traversal(root):
    """Helper to verify BST property"""
    if not root:
        return []
    return (inorder_traversal(root.left) + 
            [root.val] + 
            inorder_traversal(root.right))

# Verify BST property maintained
def test_bst_property():
    root = TreeNode(4, TreeNode(2), TreeNode(7))
    result = insertIntoBST(root, 1)
    traversal = inorder_traversal(result)
    assert traversal == sorted(traversal)  # Should be sorted

🧹 E β€” Evaluate & Optimize

Interviewer Prompts & Possible Answers:

  • "What's the time and space complexity?"
    β†’ "Time: O(h) where h is height of tree. Best case O(log n) for balanced tree, worst case O(n) for skewed tree. Space: O(h) for recursion stack, O(1) for iterative."

  • "Which approach do you prefer and why?"
    β†’ "Recursive is cleaner and more intuitive for tree problems. Iterative uses less space and avoids potential stack overflow."

  • "How does tree balance affect performance?"
    β†’ "In a balanced BST, insertion is O(log n). In a completely skewed tree, it degrades to O(n) like a linked list."

  • "Could we optimize this for repeated insertions?"
    β†’ "For many insertions, we might want to use a self-balancing BST like AVL or Red-Black tree to maintain O(log n) guarantees."

  • "What if the tree could become unbalanced after many insertions?"
    β†’ "We'd need rotation operations to rebalance, but that's beyond the scope of this problem."

  • "How does this compare to other data structures for insertion?"
    β†’ "Arrays require O(n) for sorted insertion, hash tables give O(1) average but no ordering. BST gives O(log n) with ordering maintained."

  • "What if we needed to insert multiple values efficiently?"
    β†’ "We could sort the values first and use techniques like building a balanced BST from sorted array, or batch the insertions with rebalancing."

  • "Are there any alternative insertion strategies?"
    β†’ "We could insert at root and rotate down (root insertion), but the simple leaf insertion is most common and straightforward."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment