↓Skip to main content
  1. LeetCode/

LeetCode 450: Delete Node in a BST

·2 mins· ·
LeetCode Medium Tree Binary-Search-Tree Binary-Tree
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2026-10-25

  • Submissions: Accepted ×2

Approach
#

Recurse to find the node and return the root of the subtree after deletion, so the parent can reattach it (root.left = self.deleteNode(root.left, key)).

When the node to delete is found:

  • No left child: return the right child (this also covers no children).
  • No right child: return the left child.
  • Two children: find the minimum of the right subtree (the in-order successor, keep going left), copy its value into the current node, then delete the successor from the right subtree. The successor has no left child, so deleting it always hits one of the first two cases.

My Attempts
#

Accepted on the first try; I resubmitted the same code with a comment added.

Solution
#

class Solution:
    def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
        if not root:
            return None
        if key < root.val:
            root.left = self.deleteNode(root.left, key)
        elif key > root.val:
            root.right = self.deleteNode(root.right, key)
        else:
            if not root.left:
                return root.right
            if not root.right:
                return root.left
            succ = root.right
            while succ.left:
                succ = succ.left
            root.val = succ.val
            root.right = self.deleteNode(root.right, succ.val)
        return root

Complexity
#

Time O(h): finding the node, finding the successor and deleting it each follow a single downward path. Space O(h).

Mistakes to Avoid
#

  • Return the new subtree root so the parent reattaches it; changing a local variable does not change the tree.
  • With two children, delete the successor from the right subtree after copying its value, not the original key (it has been overwritten).
  • If key is not in the tree, return the tree unchanged.

Interview Explanation
#

I recurse down and always return the subtree root after deletion so the parent can reattach it. When I find the node, if it is missing a child I return the other one; with two children I copy the smallest value of the right subtree into it and delete that node from the right subtree, which is easy because it has no left child. Time O(h).

Related

LeetCode 449: Serialize and Deserialize BST
·2 mins
LeetCode Medium String Tree Depth-First-Search Breadth-First-Search Design Binary-Search-Tree Binary-Tree
LeetCode 449 note: for a BST, pre-order without null markers is enough; deserialize recursively with bounds in O(n)
LeetCode 99: Recover Binary Search Tree
·2 mins
LeetCode Medium Tree Depth-First-Search Binary-Search-Tree Binary-Tree
LeetCode 99 note: find the inversions in the in-order sequence: the earlier node of the first inversion and the later node of the last one were swapped
LeetCode 701: Insert into a Binary Search Tree
·2 mins
LeetCode Medium Tree Binary-Search-Tree Binary-Tree
LeetCode 701 note: walk down the BST to an empty spot and attach the new node; an empty tree must return the new node
LeetCode 173: Binary Search Tree Iterator
·2 mins
LeetCode Medium Stack Tree Design Binary-Search-Tree Binary-Tree Iterator
LeetCode 173 note: flattening to an array is simple but uses O(n) space; the follow-up keeps the left spine on a stack for amortized O(1) and O(h) space
LeetCode 230: Kth Smallest Element in a BST
·1 min
LeetCode Medium Tree Depth-First-Search Binary-Search-Tree Binary-Tree
LeetCode 230 note: a BST’s in-order traversal is ascending, so stop an iterative in-order walk at the k-th node
LeetCode 98: Validate Binary Search Tree
·3 mins
LeetCode Medium Tree Depth-First-Search Binary-Search-Tree Binary-Tree
LeetCode 98 note: every node has a valid range (low, high); going left the upper bound becomes the node and going right the lower bound does; comparing parent and child is not enough