Knowledge Guide
HomeDSACompany Practice

medium Delete Node in a BST

Problem Statement

Given a root node of the binary search tree, and an integer value key, return the root of the updated BST after deleting the node having a value equal to key.

If BST doesn't contain the node having value equal to key, return the same binary tree.

Examples

Example 1:

Image
Image

Example 2:

Image
Image

Example 3:

Image
Image

Try it yourself

Try solving this question here:

✅ Solution Delete Node in a BST

Problem Statement

Given a root node of the binary search tree, and an integer value key, return the root of the updated BST after deleting the node having a value equal to key.

If BST doesn't contain the node having value equal to key, return the same binary tree.

Examples

Example 1:

  • Input: [8, 3, 10, 1, 6, null, 14, null, null, 4, 7, 13], key = 3
Image
Image
  • Expected Output: [8, 4, 10, 1, 6, null, 14, null, null, null, 7, 13]
  • Justification: After removing the node with value 3, its right subtree's smallest value (4) replaces it to maintain the BST structure.

Example 2:

  • Input: [20, 10, 30, null, 15, 25, 35], key = 10
Image
Image
  • Expected Output: [20, 15, 30, null, null, 25, 35]
  • Justification: The node 10 is removed and replaced by its right child 15 to keep the tree's integrity.

Example 3:

  • Input: [50, 30, 70, 20, 40, 60, 80], key = 10
Image
Image
  • Expected Output: [50, 30, 70, 20, 40, 60, 80]
  • Justification: The BST doesn't contain the node with value 10. So, it returns the original BST.

Solution

To solve this problem, we will traverse the BST to find the target node to be deleted. If the target node has both left and right children, we'll find its in-order successor (the smallest node in its right subtree) to replace it, ensuring the BST's properties remain intact. If the target node has only one child or no children, we'll simply remove the node and connect its parent to its child if it exists.

This approach works because it respects the BST properties by carefully choosing a replacement for the deleted node when necessary and properly handling leaf nodes and nodes with a single child. It's effective because it minimally disrupts the tree's structure, requiring no unnecessary movements or changes beyond those needed to preserve the BST properties.

Step-by-step Algorithm

  1. Check if the root is null: If the root is null, there is no tree to modify, so return null.
  2. Search for the node to delete: Traverse the tree to find the node with the value equal to the key. Keep track of the parent node as you search, as you'll need it to update the tree structure after deletion.
  3. Node not found: If the node is not found (i.e., we reach a null pointer), return the root as is because there's nothing to delete.
  4. Handle node with two children:
    • If the node to be deleted has both left and right children, find the in-order successor of the node, which is the smallest node in its right subtree.
    • Swap the value of the node to be deleted with the in-order successor's value. This effectively moves the problem of deletion to a node with fewer than two children.
    • Update the current node to the in-order successor and the parent to the in-order successor's parent for the next steps.
  5. Handle node with one or no child:
    • Determine the single child of the node (if it exists) by checking if the left child is not null. Otherwise, use the right child (which could also be null if the node has no children).
    • If the node to be deleted is the root (i.e., parent is null), then the root should be updated to this single child.
    • If the node to be deleted is not the root, update the parent's link to bypass the node to be deleted, effectively removing it from the tree. This involves setting the appropriate child pointer (left or right) of the parent to the single child of the node to be deleted.
  6. Return the possibly updated root of the tree, as the deletion of a node might have changed the tree's root (especially in cases where the root itself is deleted and has a single child or no child).

Algorithm Walkthrough

Let's consider the input:

        8
       / \
      3   10
     / \    \
    1   6    14
       / \  /
      4   7 13
  • Key to Delete: 3

Steps:

  1. Start with the root: root = 8. The root is not null, so we proceed to find the node with the key to delete.
  2. Search for the node with value 3:
    • Start from the root. Current node (cur) is 8, and its value does not match the key. Parent (parent) is initially null.
    • Move to the left child of 8 since 3 is less than 8. Now, cur = 3 and parent = 8.
    • The value of cur matches the key. Node to delete is found.
  3. Check children of node 3:
    • Node 3 has two children (1 and 6), so we need to find the in-order successor in its right subtree.
  4. Find in-order successor of node 3:
    • The in-order successor is the smallest node in the right subtree of 3. We start at node 6.
    • Move to the left child of 6 to find the smallest node, which is 4. No further left children, so succ = 4 and succParent = 6.
  5. Replace node 3 with its in-order successor 4:
    • Swap values: Now, instead of deleting 3, we delete 4 after copying its value to 3. So, the value of cur (which is 3) becomes 4.
    • Adjust pointers to delete 4. Since 4 has no left child, we directly proceed to its deletion.
  6. Handle deletion of 4 (which now effectively takes the place of 3 for deletion due to value swap):
    • Node 4 is a leaf (no children), so we simply remove it by updating its parent's link.
    • 4 is the left child of 6. So, we set the left child of succParent (6) to null.
  7. Final Tree Structure:
        8
       / \
      4   10
     / \    \
    1   6    14
         \  /
          7 13

Code

java
import java.util.LinkedList;
import java.util.Queue;

// class TreeNode {
//     int val;
//     TreeNode left, right;

//     TreeNode(int x) {
//         val = x;
//     }
// }

public class Solution {

  public TreeNode deleteNode(TreeNode root, int key) {
    if (root == null) return null;

    // Find the node to be deleted and its parent.
    TreeNode parent = null;
    TreeNode cur = root;
    while (cur != null && cur.val != key) {
      parent = cur;
      if (key < cur.val) cur = cur.left;
      else cur = cur.right;
    }
    if (cur == null) return root; // Key not found.

    // Node to be deleted is found and has two children.
    if (cur.left != null && cur.right != null) {
      // Find the in-order successor and its parent.
      TreeNode succParent = cur;
      TreeNode succ = cur.right;
      while (succ.left != null) {
        succParent = succ;
        succ = succ.left;
      }
      cur.val = succ.val; // Replace cur value with successor's value.
      cur = succ; // Move to successor.
      parent = succParent;
    }

    // Node to be deleted has one child or no child.
    TreeNode child = (cur.left != null) ? cur.left : cur.right;
    if (parent == null) {
      root = child; // The root is being deleted.
    } else if (parent.left == cur) {
      parent.left = child;
    } else {
      parent.right = child;
    }

    return root;
  }

  public static void main(String[] args) {
    Solution solution = new Solution();

    // Example 2
    TreeNode root2 = new TreeNode(20);
    root2.left = new TreeNode(10);
    root2.right = new TreeNode(30);
    root2.left.right = new TreeNode(15);
    root2.right.left = new TreeNode(25);
    root2.right.right = new TreeNode(35);

    root2 = solution.deleteNode(root2, 10);
    printTree(root2);
  }

  // Method to print the binary tree
  public static void printTree(TreeNode root) {
    if (root == null) return;

    Queue<TreeNode> queue = new LinkedList<>();
    queue.add(root);

    while (!queue.isEmpty()) {
      int levelSize = queue.size(); // Number of elements at the current level
      boolean isLastLevel = true;

      for (int i = 0; i < levelSize; i++) {
        TreeNode curr = queue.poll();

        if (curr != null) {
          // Print the value of the current node
          System.out.print(curr.val + " ");
          queue.add(curr.left);
          queue.add(curr.right);
          // If any of the children is not null, this is not the last level
          if (curr.left != null || curr.right != null) {
            isLastLevel = false;
          }
        } else {
          System.out.print("null ");
        }
      }
      // After finishing a level, if it's the last level, break out of the loop
      if (isLastLevel) {
        break;
      }
    }
  }
}

Complexity Analysis

Time Complexity

The time complexity of the algorithm is , where h is the height of the binary search tree (BST). In the worst-case scenario, the node to be deleted is located at the bottom of the tree, requiring a traversal from the root to a leaf node.

Space Complexity

The space complexity of the algorithm is for the system's call stack due to recursion during the search for the node to be deleted, as well as finding the in-order successor if necessary.

🤖 Don't fully get this? Learn it with Claude

Stuck on Delete Node in a BST? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🪜 Hint ladder (no spoilers)

Progressively stronger hints — you still solve it.

I'm working on the problem **Delete Node in a BST** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🎨 Explain the approach visually

See the technique, not just code.

Explain the optimal approach to **Delete Node in a BST** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔍 Review my solution

Catch bugs, edge cases, sub-optimality.

I'll paste my solution to **Delete Node in a BST**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔁 Drill the pattern

Lock in recognition with look-alikes.

Give me 2 problems that use the SAME underlying pattern as **Delete Node in a BST**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes