Problem Summary
You are given the root of a Binary Search Tree (BST) and an integer k.
Your task is to determine whether the tree contains two distinct nodes whose values sum to k.
Return true if such a pair exists, otherwise return false.
Example BST:
5 / \ 3 6 / \ \ 2 4 7
Example queries:
For k = 9, output is true (2 + 7).
For k = 28, output is false.
Constraints:
The BST may contain a few thousand nodes. The values may be negative or positive.
Approach 1: HashSet During DFS (Simple and Efficient)
This is the most common and straightforward solution.
Key Idea
As you traverse the tree, store all node values in a HashSet.
For each node with value x, check whether k - x is already in the set.
If yes, you found a valid pair.
If not, insert x and continue.
Why this works
A HashSet supports constant-time lookup.
You only need to check one complement per node.
The traversal explores each node once, giving an optimal time complexity.
Steps
- Create an empty HashSet.
- Traverse the tree using DFS (any order: preorder, inorder, postorder).
- For every node value
val, check:- If
(k - val)exists in the set → returntrue. - Else insert
valinto the set.
- If
- If traversal finishes and no pair is found → return
false.
Time and Space
Time: O(n)
Space: O(n)
Approach 2: Inorder Traversal + Two Pointer
This approach uses the fact that an inorder traversal of a BST produces a sorted list.
Key Idea
Convert the BST into a sorted list using inorder traversal.
Then apply the classic two-pointer technique used in sorted arrays.
Why this works
The inorder traversal guarantees sorted order.
Two pointers let you scan for the target pair in linear time.
Steps
- Perform inorder traversal to get a sorted list.
- Use left and right pointers:
- If sum < k, move left pointer.
- If sum > k, move right pointer.
- If sum == k, return
true.
- If pointers meet without finding a match, return
false.
Time and Space
Time: O(n)
Space: O(n)
Java Code (HashSet DFS Approach)
import java.util.HashSet;
import java.util.Set;
class Solution {
public boolean findTarget(TreeNode root, int k) {
Set<Integer> seen = new HashSet<>();
return dfs(root, k, seen);
}
private boolean dfs(TreeNode node, int k, Set<Integer> seen) {
if (node == null) return false;
if (seen.contains(k - node.val)) {
return true;
}
seen.add(node.val);
return dfs(node.left, k, seen) || dfs(node.right, k, seen);
}
}
Java Code (Inorder + Two Pointer Approach)
import java.util.ArrayList;
import java.util.List;
class Solution {
public boolean findTarget(TreeNode root, int k) {
List<Integer> list = new ArrayList<>();
inorder(root, list);
int left = 0;
int right = list.size() - 1;
while (left < right) {
int sum = list.get(left) + list.get(right);
if (sum == k) return true;
if (sum < k) left++;
else right--;
}
return false;
}
private void inorder(TreeNode node, List<Integer> list) {
if (node == null) return;
inorder(node.left, list);
list.add(node.val);
inorder(node.right, list);
}
}
Dry Run (Using HashSet Approach)
Consider:
5 / \ 3 6 / \ \ 2 4 7
k = 9
Traversal Steps
Start at node 5:
- seen = {}
- Complement = 4 (not in seen), add 5 → seen = {5}
Move to node 3:
- Complement = 6 (not in seen), add 3 → seen = {3, 5}
Move to node 2:
- Complement = 7 (not in seen), add 2 → seen = {2, 3, 5}
Move to node 4:
- Complement = 5 (found in seen) → return true
Pair found: 4 + 5 = 9
