[Easy] 938. Range Sum of BST
Given the root node of a binary search tree and two integers low and high, return the sum of values of all nodes with a value in the inclusive range [low, high].
Examples
Example 1:
Input: root = [10,5,15,3,7,null,18], low = 7, high = 15
Output: 32
Explanation: Nodes 7, 10, and 15 are in the range [7, 15]. 7 + 10 + 15 = 32.
Example 2:
Input: root = [10,5,15,3,7,13,18,1,null,6], low = 6, high = 10
Output: 23
Explanation: Nodes 6, 7, and 10 are in the range [6, 10]. 6 + 7 + 10 = 23.
Constraints
- The number of nodes in the tree is in the range
[1, 2 * 10^4]. 1 <= Node.val <= 10^51 <= low <= high <= 10^5- All
Node.valare unique.
Thinking Process
- BST Property: Use BST ordering to skip entire subtrees
- Trees have no cycles — recursion is natural.
- Combine results from left and right subtrees at each node.
- Base case is usually
null; height drives stack space.
Common Approaches
Typical techniques for this pattern:
| Approach | Time | Space | Notes |
|---|---|---|---|
| Recursive DFS (this problem) | O(n) | O(h) stack | Natural for trees and graphs |
| Iterative DFS (stack) | O(n) | O(n) | Avoid recursion depth limits |
| DFS with memoization | O(n) | O(n) | Overlapping subproblems on graphs |
| Backtracking DFS | O(2^n) typical | O(n) | Enumerate choices with pruning |
Solution
Time Complexity: O(n) worst case, but often better due to pruning
Space Complexity: O(h) where h is the height of the tree (recursion stack)
The key insight is to leverage BST properties to prune branches that cannot contain values in the range [low, high].
Solution: Recursive DFS with Pruning
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def rangeSumBST(self, root, low, high):
if root == None:
return 0
if root.val > high:
return self.rangeSumBST(root.left, low, high)
elif root.val < low:
return self.rangeSumBST(root.right, low, high)
return root.val + self.rangeSumBST(root.left, low, high) + self.rangeSumBST(root.right, low, high)
Solution Explanation
Approach: Recursive DFS (this problem)
Key idea: 1. BST Property: Use BST ordering to skip entire subtrees
How the code works:
- BST Property: Use BST ordering to skip entire subtrees
- Trees have no cycles — recursion is natural.
- Combine results from left and right subtrees at each node.
- Base case is usually
null; height drives stack space.
Walkthrough — input root = [10,5,15,3,7,null,18], low = 7, high = 15, expected output 32:
Nodes 7, 10, and 15 are in the range [7, 15]. 7 + 10 + 15 = 32.
| Approach | Time | Space | Pros | Cons | |———-|——|——-|——|——| | Recursive with Pruning | O(n) worst, often better | O(h) | Simple, efficient | Recursion overhead | | Iterative with Stack | O(n) worst, often better | O(h) | No recursion | More code | | Inorder (No Pruning) | O(n) | O(h) | Simple | Less efficient |
Algorithm Breakdown
Base Case
if(root == None) return 0
Why: Empty subtree contributes 0 to the sum.
Pruning Cases
if root.val > high:
return rangeSumBST(root.left, low, high)
Why: If current value > high, all values in right subtree are also > high (BST property). Only search left subtree.
def if(self, low):
return rangeSumBST(root.right, low, high)
Why: If current value < low, all values in left subtree are also < low (BST property). Only search right subtree.
Include Current Node
return root.val + rangeSumBST(root.left, low, high) + rangeSumBST(root.right, low, high)
Why: Current node is in range [low, high], so:
- Include its value
- Search both subtrees (they might contain valid values)
Complexity
| Approach | Time | Space | Pros | Cons | |———-|——|——-|——|——| | Recursive with Pruning | O(n) worst, often better | O(h) | Simple, efficient | Recursion overhead | | Iterative with Stack | O(n) worst, often better | O(h) | No recursion | More code | | Inorder (No Pruning) | O(n) | O(h) | Simple | Less efficient |
Implementation Details
Why Pruning Works
BST Property:
For node with value v:
- Left subtree: all values < v
- Right subtree: all values > v
Pruning Logic:
v > high→ Right subtree values > v > high → Skip rightv < low→ Left subtree values < v < low → Skip left
Recursive Call Structure
class Solution:
def rangeSumBST(self, root, low, high):
if root == None:
return 0
stk = []
stk.append(root)
total = 0
while stk:
node = stk[-1]
stk.pop()
if node == None:
continue
if node.val > high:
stk.append(node.left)
elif node.val < low:
stk.append(node.right)
else:
total += node.val
stk.append(node.left)
stk.append(node.right)
return total
Breakdown:
root->val: Current node’s value (if in range)rangeSumBST(root->left, ...): Sum from left subtreerangeSumBST(root->right, ...): Sum from right subtree- Add all three together
Common Mistakes
- Single node: Tree with one node
- All nodes in range: Entire tree contributes to sum
- No nodes in range: Return 0
- Range at boundaries: low or high equals node values
-
Skewed tree: Left-skewed or right-skewed BST
- Forgetting BST property: Not pruning subtrees
- Wrong comparison: Using
>=or<=incorrectly - Not handling null: Forgetting null checks
- Inclusive range: Not including boundary values correctly
- Traversing unnecessary subtrees: Not using pruning optimization
Optimization Tips
- Use BST pruning: Always leverage BST properties for efficiency
- Early termination: Can optimize further if needed (not applicable here)
- Iterative for deep trees: Use iterative approach to avoid stack overflow
Related Problems
- 700. Search in a Binary Search Tree - Similar BST traversal
- 701. Insert into a Binary Search Tree - BST modification
- 230. Kth Smallest Element in a BST - BST traversal with counting
- 98. Validate Binary Search Tree - BST property validation
Real-World Applications
- Database Queries: Range queries in B-trees (similar to BST)
- Interval Trees: Finding values in ranges
- Statistics: Summing values in a range
- Data Analysis: Aggregating data within bounds
Pattern Recognition
This problem demonstrates the “BST Range Query” pattern:
1. Use BST property to prune branches
2. If current value outside range → skip appropriate subtree
3. If current value in range → include and search both subtrees
4. Recursively combine results
Similar problems:
- Search in BST
- Count nodes in range
- Find values in range
Why Pruning is Important
Without Pruning:
- Visits all n nodes: O(n) time
- No benefit from BST structure
With Pruning:
- Skips subtrees outside range
- Often visits fewer nodes
- Still O(n) worst case, but much better average case
- Especially efficient when range is narrow or at tree edges
Step-by-Step Trace: root = [10,5,15,3,7,13,18,1,null,6], low = 6, high = 10
Tree Structure:
10
/ \
5 15
/ \ / \
3 7 13 18
/ /
1 6
Traversal:
1. root=10, val=10
- 10 is in [6,10] → include 10
- Search left (5) and right (15)
Sum = 10 + ...
2. root=5, val=5
- 5 < 6 (low) → skip left (3), search right (7)
Sum = 10 + ...
3. root=7, val=7
- 7 is in [6,10] → include 7
- Search left (6) and right (null)
Sum = 10 + 7 + ...
4. root=6, val=6
- 6 is in [6,10] → include 6
- Search left (null) and right (null)
Sum = 10 + 7 + 6 + ...
5. root=15, val=15
- 15 > 10 (high) → skip right (18), search left (13)
Sum = 10 + 7 + 6 + ...
6. root=13, val=13
- 13 > 10 (high) → skip right, search left (null)
Sum = 10 + 7 + 6
Final: 10 + 7 + 6 = 23
BST Property Recap
Binary Search Tree (BST) Properties:
- Left subtree: All values < root value
- Right subtree: All values > root value
- Both subtrees: Are also BSTs (recursive property)
Why This Helps:
- If
root->val > high, entire right subtree is > high - If
root->val < low, entire left subtree is < low - We can skip entire subtrees without checking individual nodes
Key Takeaways
- BST Property: Use BST ordering to skip entire subtrees
- Pruning Optimization: Don’t traverse subtrees that can’t contain valid values
- Inclusive Range: Include nodes where
low <= val <= high - Recursive Structure: Natural fit for tree traversal
References
- LC 938: Range Sum of BST on LeetCode
- LeetCode Discuss — LC 938: Range Sum of BST
- LeetCode Editorial (may require premium)