Practice
Solution
Step 1: Perform inorder traversal on BST with nodes 1, 2, 3
Inorder traversal yields nodes in sorted order: [1, 2, 3].Step 2: Iteratively build balanced BST choosing middle node
Middle index is 1 (0-based), so node with value 2 becomes root.Final Answer:
Option B -> Option BQuick Check:
Middle of [1,2,3] is 2 -> root value 2 [OK]
- Choosing left or right middle always, skewing tree
- Confusing preorder with inorder traversal results
- Forgetting to reset left/right pointers causing cycles
total returned by rangeSumBST?Solution
Step 1: Trace initial stack and total
Start with stack=[10], total=0.Step 2: Pop 10 (in range), add 10, push left(5) and right(15)
total=10, stack=[5,15]Step 3: Pop 15 (in range), add 15, push left(null) and right(null)
total=25, stack=[5,null,null]Step 4: Pop null (skip), then pop null (skip), then pop 5 (less than low=7), push right(null)
total=25, stack=[null]Step 5: Pop null (skip), stack empty, return total=25
5 is less than low, so it is skipped and not added.Final Answer:
Option A -> Option AQuick Check:
Sum includes 10 and 15 only, total=25 [OK]
- Adding nodes outside range
- Forgetting to push children after adding node
def insertIntoBST(root, val):
if root is None:
return TreeNode(val)
curr = root
while curr:
if val < curr.val:
if curr.left is None:
curr.left = TreeNode(val)
return root
curr = curr.left
else:
if curr.right is None:
curr.right = TreeNode(val)
return root
curr = curr.right
return root
Solution
Step 1: Identify traversal cost
Insertion requires traversing from root down to a leaf where the new node is inserted.Step 2: Relate traversal to tree height
In worst case, the tree is skewed, so height h can be up to n, but complexity is expressed as O(h).Final Answer:
Option B -> Option BQuick Check:
Traversal cost dominates insertion -> O(h) [OK]
- Assuming O(1) because insertion is at leaf
- Confusing height h with number of nodes n
- Assuming BST is always balanced
def lowestCommonAncestor(root, p, q):
current = root
while current:
if p.val < current.val and q.val < current.val:
current = current.left
elif p.val > current.val and q.val > current.val:
current = current.right
else:
return current
Solution
Step 1: Analyze comparison operators
Using '<=' and '>=' causes the loop to move past the node when p or q equals current, missing the case where current is ancestor of itself.Step 2: Correct operator usage
Changing to '<' and '>' ensures the loop stops at the correct ancestor node, including when one node is ancestor of the other.Final Answer:
Option A -> Option AQuick Check:
Inclusive comparisons skip valid ancestor nodes [OK]
- Assuming ancestor must be strictly above nodes
- Ignoring null root edge cases
- Returning too early without validation
Solution
Step 1: Understand duplicates stored in right subtree
Duplicates appear as nodes with the same key in the right subtree, so deleting one occurrence requires deleting all duplicates to maintain correctness.Step 2: Adapt deletion to remove all duplicates
After deleting the target node, recursively delete all nodes in the right subtree with the same key to remove duplicates fully.Step 3: Why other options fail
Ignoring duplicates leaves them in tree (A), replacing with predecessor doesn't address duplicates (B), and modifying successor search (D) doesn't remove all duplicates.Final Answer:
Option D -> Option DQuick Check:
Deleting all duplicates ensures BST correctness with duplicates allowed [OK]
- Deleting only one node leaves duplicates
- Using predecessor doesn't solve duplicates
- Modifying successor search misses duplicates
