💡 Adding 7 completes the sum of all in-range nodes found so far.
traverse
Pop null from stack and skip
Pop a null node from the stack and skip processing since it does not exist.
💡 Null nodes represent absent children and do not affect the sum or traversal.
Line:if node:
...
else:
continue
💡 Skipping null nodes prevents errors and unnecessary processing.
traverse
Pop null from stack and skip
Pop another null node from the stack and skip processing.
💡 Multiple null nodes appear as children of leaf nodes and are ignored.
Line:if node:
...
else:
continue
💡 Null nodes mark ends of branches.
traverse
Pop node 18 from stack
Pop node 18 from the stack to process it next.
💡 Node 18 is greater than the high bound and will be pruned accordingly.
Line:node = stack.pop()
💡 Node 18 will be checked against the range to decide pruning.
compare
Node 18 is greater than high, push only left child
Since 18 is greater than 15, skip right child and push only left child (null) onto the stack.
💡 Pruning right subtree avoids unnecessary checks since all right nodes are larger.
Line:else: # node.val > high
stack.append(node.left)
💡 BST property allows skipping right subtree when node value is above high.
traverse
Pop null from stack and skip
Pop a null node from the stack and skip processing.
💡 Null nodes mark ends of branches and are ignored.
Line:if node:
...
else:
continue
💡 Skipping null nodes prevents errors and unnecessary processing.
traverse
Pop null from stack and skip
Pop the last null node from the stack and skip processing.
💡 All nodes have been processed or pruned; traversal is about to end.
Line:if node:
...
else:
continue
💡 Traversal ends when stack is empty.
reconstruct
Traversal complete, return total sum
Stack is empty, traversal is complete. Return the total sum of nodes within range.
💡 The final sum is the answer to the problem.
Line:return total
💡 The sum 32 includes all nodes with values 7, 10, and 15.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def rangeSumBST(root, low, high):
stack = [root] # STEP 1
total = 0 # STEP 1
while stack: # STEP 2 loop start
node = stack.pop() # STEP 2
if node: # STEP 3
if low <= node.val <= high: # STEP 4
total += node.val # STEP 4
stack.append(node.left) # STEP 4
stack.append(node.right)# STEP 4
elif node.val < low: # STEP 5
stack.append(node.right)# STEP 5
else: # node.val > high # STEP 6
stack.append(node.left) # STEP 6
return total # STEP 16
if __name__ == '__main__':
root = TreeNode(10, TreeNode(5, TreeNode(3), TreeNode(7)), TreeNode(15, None, TreeNode(18)))
print(rangeSumBST(root, 7, 15)) # Output: 32
📊
Range Sum of BST - Watch the Algorithm Execute, Step by Step
Watching this step-by-step traversal reveals how BST properties help skip unnecessary nodes, making the algorithm efficient and intuitive.
Step 1/16
·Active fill★Answer cell
105153718
Current node: 0
105153718
105153718
Current node: 2
105153718
105153718
Current node: 1
105153718
105153718
Current node: 4
105153718
105153718
105153718
105153718
Current node: 5
105153718
105153718
105153718
105153718
105153718
Return: 32
Key Takeaways
✓ BST properties allow pruning subtrees that cannot contain values in the range, improving efficiency.
This pruning is not obvious from code alone but is clear when watching which nodes are skipped.
✓ The iterative DFS with a stack simulates recursion and shows explicit control over traversal order.
Seeing the stack contents change step-by-step helps understand traversal mechanics.
✓ Only nodes within the range contribute to the sum, and their children are explored; nodes outside the range prune one subtree.
This decision logic is clearer when watching each node's value compared to the range.
Practice
(1/5)
1. Consider the following Python code implementing the Morris inorder traversal to recover a BST with two swapped nodes. Given the input tree with nodes [3,1,4,null,null,2] where nodes 2 and 3 are swapped, what is the value of the variable second.val after the traversal completes?
easy
A. 3
B. 2
C. 4
D. 1
Solution
Step 1: Trace inorder traversal with Morris method
The inorder traversal visits nodes in order: 1, 3, 2, 4. The violations are detected when prev.val > current.val: first at (3,2).
Step 2: Identify swapped nodes
First violation sets first=3, second=2. No second violation occurs, so second remains 2.
Final Answer:
Option B -> Option B
Quick Check:
Second node detected is the node with value 2 [OK]
Hint: Second swapped node is the smaller value in violation [OK]
Common Mistakes:
Confusing first and second nodes
Missing second violation for adjacent swaps
Off-by-one in traversal order
2. You are given a binary tree and need to determine if it satisfies the property that for every node, all nodes in its left subtree have smaller values and all nodes in its right subtree have larger values, with no duplicates allowed. Which approach guarantees an optimal solution to this problem?
easy
A. Check each node by comparing it only with its immediate children recursively.
B. Apply a greedy algorithm that validates nodes as soon as they are visited.
C. Use dynamic programming to store subtree min and max values and combine results bottom-up.
D. Perform an inorder traversal and verify that the node values are strictly increasing.
Solution
Step 1: Understand BST property
The BST property requires all left subtree nodes to be less than the current node and all right subtree nodes to be greater, strictly increasing in inorder traversal.
Step 2: Recognize inorder traversal pattern
Inorder traversal of a valid BST produces a strictly increasing sequence of values, so verifying this sequence guarantees correctness efficiently.
Final Answer:
Option D -> Option D
Quick Check:
Inorder traversal yields sorted values for BST [OK]
Hint: Inorder traversal of BST is strictly increasing [OK]
Common Mistakes:
Only comparing node with immediate children
Using greedy checks without global ordering
Confusing subtree min/max with inorder sequence
3. What is the worst-case time complexity of the optimized recursive BST node deletion algorithm that uses the in-order successor to replace a node with two children?
medium
A. O(h) where h is the height of the BST
B. O(h^2) due to recursive calls and successor search
C. O(log n) always, since BST is balanced
D. O(n) where n is the total number of nodes in the BST
Solution
Step 1: Identify height-based operations
Deletion involves searching down the tree (O(h)) and finding the in-order successor, which is also O(h) in worst case.
Step 2: Combine operations and recursion
Successor search and recursive deletion happen along a path of length h, so total time is O(h), not O(h^2).
Final Answer:
Option A -> Option A
Quick Check:
Time proportional to tree height, not total nodes or squared height [OK]
Hint: Deletion time depends on tree height, not total nodes [OK]
Common Mistakes:
Assuming balanced BST always (log n)
Confusing recursion depth with squared complexity
Thinking successor search adds extra factor
4. The following code attempts to search for a value in a BST. Identify the line containing the subtle bug that can cause incorrect behavior or inefficiency.
def searchBST(root, val):
if root is None:
return None
if root.val == val:
return root
left_search = searchBST(root.left, val)
if left_search is not None:
return left_search
return searchBST(root.right, val)
medium
A. Line 5: left_search = searchBST(root.left, val)
B. Line 4: if root.val == val: return root
C. Line 2: if root is None: return None
D. Line 7: return searchBST(root.right, val)
Solution
Step 1: Understand the code logic
This code searches both left and right subtrees regardless of BST property.
Step 2: Identify inefficiency bug
Line 5 always searches left subtree even if val > root.val, ignoring BST property and causing O(n) time.
Hint: Searching both subtrees ignores BST property [OK]
Common Mistakes:
Not pruning search using BST property
5. The following code attempts to validate a BST using inorder traversal. Which line contains a subtle bug that can cause incorrect results on some inputs?
medium
A. Line checking if node is null (if not node: return true)
B. Line updating prev[0] = node.val
C. Line comparing node.val < prev[0] instead of node.val <= prev[0]
D. Line calling inorder(node.left)
Solution
Step 1: Identify BST strict inequality
BST requires node.val to be strictly greater than previous inorder value; using < instead of <= allows duplicates.
Step 2: Understand impact of bug
Using node.val < prev[0] misses the case when node.val == prev[0], incorrectly allowing duplicates and invalid BSTs.
Final Answer:
Option C -> Option C
Quick Check:
Strict inequality check is essential to reject duplicates [OK]
Hint: BST nodes must be strictly increasing in inorder traversal [OK]
Common Mistakes:
Allowing duplicates by using < instead of <=
Not resetting prev between calls
Only comparing immediate children
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.