Last Updated: April 2, 2026
This is the classic Two Sum problem, but the input is a BST instead of an array. We need to find whether any two distinct nodes in the tree have values that add up to k.
The interesting thing here is that we have two angles to work with. First, this is a "find two numbers that sum to a target" problem, which we know how to solve with a hash set. Second, the input is a BST, which means the values are sorted if we do an inorder traversal. That sorted property opens the door to a two-pointer approach.
The key question is: do we treat this as a generic tree problem (ignoring the BST property) and use a hash set, or do we exploit the BST's sorted order for a two-pointer solution? Both work, and each teaches something different.
Number of nodes in [1, 10^4] -- With up to 10,000 nodes, O(n) and O(n log n) solutions are both fine. Even O(n^2) would pass, though it is unnecessary.Node values in [-10^4, 10^4] -- Values can be negative. The target k can also be negative. Our solution needs to handle negative complements.At least 1 node -- We do not need to handle an empty tree, but a single-node tree should return false since we need two distinct nodes.Let's start with the simplest idea. Forget that the input is a BST for a moment. Treat it as a regular tree and apply the same logic we would use for the original Two Sum problem on an array.
For each node we visit, we compute its complement: k - node.val. If that complement is already in a set of values we have seen so far, we found our pair. If not, we add the current node's value to the set and keep traversing.
This is a direct application of the hash set technique. The tree traversal (DFS or BFS, either works) replaces the array iteration from the original Two Sum. The hash set does the heavy lifting of O(1) lookups.
complement = k - node.val.node.val to the set.This solution is already O(n) in time, but we completely ignored the BST property. The BST gives us something valuable: an inorder traversal produces a sorted sequence. Can we exploit that sorted order to use a two-pointer approach instead?
Here is where the BST property becomes useful. If we do an inorder traversal of a BST, we get all the values in sorted order. And finding two numbers in a sorted array that sum to a target is a classic two-pointer problem (Two Sum II).
So the plan is straightforward: flatten the BST into a sorted list via inorder traversal, then run two pointers from both ends. If the sum of the two pointed values is too small, move the left pointer right. If too large, move the right pointer left. If equal, we found our pair.
This approach makes the BST connection to sorted arrays explicit. It is a good demonstration of how recognizing the underlying structure of your input can unlock familiar techniques.
left at the start of the list, right at the end.left < right: a. Compute sum = list[left] + list[right].
b. If sum == k, return true.
c. If sum < k, increment left (we need a larger sum).
d. If sum > k, decrement right (we need a smaller sum).
The two-pointer technique works on sorted arrays because of a simple invariant. If the sum of the smallest remaining element and the largest remaining element is less than the target, the smallest element cannot be part of any valid pair (even pairing it with the largest is not enough), so we discard it by moving left forward. Symmetrically, if the sum is too large, the largest element is too big for any remaining pair, so we discard it by moving right backward. This guarantees we never skip a valid pair.
Both approaches so far use O(n) extra space. Is there a way to do the two-pointer scan without materializing the entire sorted list? If we could walk the BST from both ends simultaneously, we could run the two-pointer logic directly on the tree.
This approach takes the two-pointer idea from Approach 2 and applies it directly on the BST, without first collecting all values into a list. The trick is to use two iterators: one that produces values in ascending order (normal inorder: left, root, right) and another that produces values in descending order (reverse inorder: right, root, left).
Think of it like having two fingers on the tree. One finger starts at the leftmost node (the smallest value) and moves right. The other starts at the rightmost node (the largest value) and moves left. At each step, we compare their sum to k and decide which finger to advance, exactly like the two-pointer technique on a sorted array.
We implement each iterator using an explicit stack. The forward iterator pushes all left children to get to the minimum, then steps to the right subtree. The reverse iterator does the mirror: pushes all right children to get to the maximum, then steps to the left subtree.
leftVal) and largest (rightVal).leftVal < rightVal: a. Compute sum = leftVal + rightVal.
b. If sum == k, return true.
c. If sum < k, advance the forward iterator: move to the right child of the current node, then push all its left children. Pop the next value.
d. If sum > k, advance the reverse iterator: move to the left child of the current node, then push all its right children. Pop the next value.
This is conceptually identical to Approach 2, but instead of materializing the entire sorted list, we lazily produce values on demand. The forward stack always has the next smallest value ready to pop, and the reverse stack always has the next largest value ready. We only explore as much of the tree as needed. The termination condition leftNode != rightNode works because in a BST, the forward and reverse iterators will eventually converge on the same node. When they point to the same node, we have exhausted all possible pairs without finding a match.