AlgoMaster Logo

Two Sum IV - Input is a BST

Last Updated: April 2, 2026

easy

Understanding the Problem

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.

Key Constraints:

  • 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.

Approach 1: DFS with Hash Set

Intuition

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.

Algorithm

  1. Create an empty hash set to store node values we have visited.
  2. Start a DFS traversal from the root.
  3. At each node, compute the complement: complement = k - node.val.
  4. If the complement exists in the set, return true.
  5. Otherwise, add node.val to the set.
  6. Recursively check the left and right subtrees. If either returns true, return true.
  7. If we finish traversing the entire tree without finding a pair, return false.

Example Walkthrough

1Start DFS at root 5. complement = 9 - 5 = 4. set = {} (not found). Add 5. set = {5}
5visit32467
1/4

Code

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?

Approach 2: Inorder Traversal + Two Pointers

Intuition

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.

Algorithm

  1. Perform an inorder traversal of the BST to collect all values into a sorted list.
  2. Initialize two pointers: left at the start of the list, right at the end.
  3. While 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).

  1. If the pointers meet without finding a pair, return false.

Example Walkthrough

1Inorder traversal of BST gives sorted array. k = 9. Place left at index 0, right at index 5
0
2
left
1
3
2
4
3
5
4
6
5
7
right
1/2

Code

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.

Approach 3: BST Iterator Two Pointers

Intuition

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.

Algorithm

  1. Initialize a forward stack by pushing all left children starting from the root (this positions us at the smallest value).
  2. Initialize a reverse stack by pushing all right children starting from the root (this positions us at the largest value).
  3. Pop the top of each stack to get the current smallest (leftVal) and largest (rightVal).
  4. While 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.

  1. If the pointers meet or cross, return false.

Example Walkthrough

1Initialize forward stack: push 5 -> 3 -> 2. Forward points to 2 (smallest). Initialize reverse stack: push 5 -> 6 -> 7. Reverse points to 7 (largest)
532left=2467right=7
1/2

Code