Practice
from typing import Optional
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def kthSmallest(root: Optional[TreeNode], k: int) -> int:
stack = []
current = root
count = 0
while current or stack:
while current:
stack.append(current)
current = current.left
current = stack.pop()
count += 1
if count == k:
return current.val
current = current.right
# Tree:
# 3
# / \
# 1 4
# \
# 2
root = TreeNode(3)
root.left = TreeNode(1)
root.right = TreeNode(4)
root.left.right = TreeNode(2)
print(kthSmallest(root, 2))
Solution
Step 1: Trace the inorder traversal steps
Stack initially empty, current=root(3). Push 3, move left to 1. Push 1, move left to None. Pop 1 (count=1), move right to 2.Step 2: Continue traversal to find kth=2
Push 2, move left None. Pop 2 (count=2), return 2 as kth smallest.Final Answer:
Option C -> Option CQuick Check:
Second smallest in BST is 2 [OK]
- Off-by-one counting of k
- Returning before incrementing count
Solution
Step 1: Understand BST property and inorder traversal
Inorder traversal of a BST produces a sorted array of node values.Step 2: Apply two-pointer technique on sorted array
Using two pointers at start and end, we can efficiently find if two values sum to k in O(n) time and O(n) space.Final Answer:
Option A -> Option AQuick Check:
Inorder + two pointers is optimal and uses BST ordering [OK]
- Trying nested loops directly on BST nodes without flattening
- Assuming greedy approach works without sorting
- Using DP which is unnecessary here
class BSTIterator:
def __init__(self, root):
self.current = root
self.next_val = None
self._advance()
def _advance(self):
while self.current:
if not self.current.left:
self.next_val = self.current.val
self.current = self.current.right
return
else:
pre = self.current.left
while pre.right and pre.right != self.current:
pre = pre.right
if not pre.right:
pre.right = self.current
self.current = self.current.left
else:
# BUG: Missing restoration of thread
self.next_val = self.current.val
self.current = self.current.right
Solution
Step 1: Identify thread restoration step
In Morris traversal, after visiting a node, the temporary thread (pre.right) must be reset to null to restore the tree.Step 2: Locate missing restoration
The code omits resetting pre.right = None in the else block, causing the tree to remain modified after iteration.Final Answer:
Option A -> Option AQuick Check:
Missing thread removal corrupts tree structure [OK]
- Forgetting to remove threads
- Misplacing next_val assignment
- Incorrect current pointer updates
Solution
Step 1: Understand pruning logic
If node.val < low, left subtree nodes are smaller and cannot be in range, so left subtree should be skipped.Step 2: Identify incorrect line
Appending node.left when node.val < low causes unnecessary traversal of left subtree, violating pruning. It should append node.right instead.Final Answer:
Option A -> Option AQuick Check:
Correct pruning requires appending node.right only when node.val < low [OK]
- Appending wrong subtree when pruning
- Forgetting to check null nodes
Solution
Step 1: Identify time complexity
The algorithm visits each node exactly once in inorder traversal, so time is O(n).Step 2: Identify space complexity
Space is O(h) due to recursion stack, where h is the height of the tree; no extra arrays store all nodes.Final Answer:
Option A -> Option AQuick Check:
Linear time and stack space proportional to tree height [OK]
- Confusing recursion stack space with storing all nodes
- Assuming O(n log n) due to sorting
- Ignoring recursion stack space
