Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST.
Basically, the deletion can be divided into two stages:
Example 1:
Input: root = [5,3,6,2,4,null,7], key = 3 Output: [5,4,6,2,null,null,7] Explanation: Given key to delete is 3. So we find the node with value 3 and delete it. One valid answer is [5,4,6,2,null,null,7], shown in the above BST. Please notice that another valid answer is [5,2,6,null,4,null,7] and it's also accepted.![]()
Example 2:
Input: root = [5,3,6,2,4,null,7], key = 0 Output: [5,3,6,2,4,null,7] Explanation: The tree does not contain a node with value = 0.
Example 3:
Input: root = [], key = 0 Output: []
Constraints:
[0, 104]
.-105 <= Node.val <= 105
root
is a valid binary search tree.-105 <= key <= 105
Follow up: Could you solve it with time complexity O(height of tree)
?
This problem involves deleting a node with a given key from a Binary Search Tree (BST). The solution employs a recursive approach with several cases to handle:
1. Base Case: If the root is null
(empty tree), return null
.
2. Recursive Search:
key
is less than the current node's value, recursively call deleteNode
on the left subtree.key
is greater than the current node's value, recursively call deleteNode
on the right subtree.3. Node Found (key == root.val):
This is where the deletion logic resides. There are three sub-cases:
Case A: Node is a leaf node (no children): Simply return null
to remove the node.
Case B: Node has one child: Return the single child node to replace the node being deleted.
Case C: Node has two children: This is the most complex case. The solution employs the following strategy:
Time Complexity Analysis:
The time complexity is O(H), where H is the height of the BST. In the worst case (a skewed tree), H can be equal to N (the number of nodes), resulting in O(N) time complexity. In the best case (a balanced tree), H is log₂(N), leading to O(log₂(N)) time complexity. The recursive calls only traverse a path down the tree, hence the height dependency.
Space Complexity Analysis:
The space complexity is O(H) in the worst case due to the recursive call stack. Again, for a skewed tree, this becomes O(N), while for a balanced tree, it's O(log₂(N)).
Code Explanation (Python Example):
The Python code directly implements the algorithm described above:
class Solution:
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
if root is None: # Base case: empty tree
return None
if root.val > key: # Recursive search on left subtree
root.left = self.deleteNode(root.left, key)
return root
elif root.val < key: # Recursive search on right subtree
root.right = self.deleteNode(root.right, key)
return root
else: # Node found (key == root.val)
if root.left is None: # Case A or B: One or zero children
return root.right
elif root.right is None:
return root.left
else: # Case C: Two children
node = root.right
while node.left: #Find inorder successor
node = node.left
node.left = root.left # Connect left subtree to successor
root = root.right # Replace the current node with its right subtree
return root
The other languages (Java, C++, Go, TypeScript, Rust) follow the same logic, adapting the syntax and data structures specific to each language. The core algorithm remains consistent.