Given the root of a binary search tree and an integer target, return true if there exist two different nodes in the BST whose values sum to target, and false otherwise.
The tree is given in level-order (breadth-first), using null for missing children.
Input: root = [5, 3, 6, 2, 4, null, 7], target = 9 Output: true 2 + 7 = 9 (also 5 + 4).
Input: root = [5, 3, 6, 2, 4, null, 7], target = 28 Output: false No two distinct node values sum to 28.
- The number of nodes is in the range [1, 10^4] - -10^5 <= Node.val <= 10^5 - -2 * 10^5 <= target <= 2 * 10^5 - All Node.val are unique
This is two-sum on a tree. The hash-set approach is the direct translation: traverse the tree, and for each node check whether its complement target - val has already been seen. It's O(n) time but O(n) extra space and doesn't use the BST ordering at all.
The approach that uses the BST flattens it with an inorder traversal into a sorted array, then runs the classic two-pointer sweep: a pointer at each end, move the left pointer right when the sum is too small and the right pointer left when it's too big. Same O(n) time, but the logic is the standard sorted-array two-sum — and it generalises to the "two BSTs" variant.
“Must the two nodes be different?”
Yes — a single node used twice does not count.
“Can values be negative?”
Assume the given range; the logic is unchanged either way.
Inorder gives me the values sorted, then it's the standard two-pointer two-sum from both ends.
If I can't afford the array, a hash set of seen values with a complement check also works in one pass.
Worked example — BST [5, 3, 6, 2, 4, null, 7], target = 9
inorder = [2, 3, 4, 5, 6, 7] i=2,j=7 -> 9 == target -> true
That turns the tree problem into sorted-array two-sum.
Too-small sum ⇒ advance the left pointer; too-big ⇒ retreat the right pointer.
The complement-check works on any binary tree, at the cost of O(n) space.
| Hash set of seen | Inorder + two pointers | |
|---|---|---|
| Idea | Check target - val against a set while traversing | Flatten to sorted, sweep from both ends |
| Time | O(n) | O(n) |
| Space | O(n) | O(n) for the array, O(1) sweep |
| Uses BST order |
Both are O(n); the two-pointer version leans on the BST's sorted inorder. Full code is in the Approaches selector below.
Key takeaway
Inorder-flatten the BST to a sorted array, then two-pointer two-sum from both ends. Or, without the array, traverse and check each node's complement against a hash set. Both O(n).
a = inorder(root) # sorted
i, j = 0, len(a)-1
while i < j:
s = a[i] + a[j]
if s == target: return True
if s < target: i += 1 else: j -= 1
return False