Two Sum in BST in DSA Typescript - Time & Space Complexity
We want to know how the time needed to find two numbers that add up to a target grows as the tree gets bigger.
How does the search time change when the number of nodes increases?
Analyze the time complexity of the following code snippet.
function findTarget(root: TreeNode | null, k: number): boolean {
const set = new Set();
function dfs(node: TreeNode | null): boolean {
if (!node) return false;
if (set.has(k - node.val)) return true;
set.add(node.val);
return dfs(node.left) || dfs(node.right);
}
return dfs(root);
}
This code searches the BST to find if two values sum to k by traversing all nodes once and checking complements in a set.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive traversal of each node in the BST.
- How many times: Each node is visited exactly once during the depth-first search.
As the number of nodes grows, the function visits each node once, so the work grows directly with the number of nodes.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 visits and set checks |
| 100 | About 100 visits and set checks |
| 1000 | About 1000 visits and set checks |
Pattern observation: The operations increase linearly as the tree size increases.
Time Complexity: O(n)
This means the time to find the two sum grows directly with the number of nodes in the tree.
[X] Wrong: "Because the tree is a BST, searching for pairs is faster than visiting all nodes."
[OK] Correct: The code visits every node once to check pairs, so it still takes time proportional to all nodes, not less.
Understanding this helps you explain how traversing a tree and using extra space for quick lookups works together, a common pattern in coding problems.
"What if we used an in-order traversal to create a sorted array first, then used two pointers to find the sum? How would the time complexity change?"
Practice
Two Sum in BST problem?Solution
Step 1: Understand the problem statement
The problem asks to find two nodes in a Binary Search Tree (BST) such that their values add up to a given target sum.Step 2: Identify the goal
The goal is to check if such a pair exists, not to find maximum, count nodes, or check balance.Final Answer:
Find two nodes in a BST whose values add up to a target sum -> Option BQuick Check:
Two Sum in BST = Find pair with target sum [OK]
- Confusing with finding max or min value
- Thinking it counts nodes instead of finding pairs
- Assuming it checks tree balance
Solution
Step 1: Check correct TypeScript class syntax for BST node
class TreeNode { val: number; left: TreeNode | null; right: TreeNode | null; constructor(val: number) { this.val = val; this.left = null; this.right = null; } } defines a class with number value and nullable left/right children, matching BST node structure.Step 2: Compare other options
function TreeNode(val) { this.val = val; this.left = null; this.right = null; } is JavaScript function style, not TypeScript class. interface TreeNode { val: string; left: TreeNode; right: TreeNode; } uses string type for val and non-nullable children, which is incorrect. type TreeNode = { val: number; left?: TreeNode; right?: TreeNode; } uses optional properties but lacks constructor and proper null handling.Final Answer:
class TreeNode { val: number; left: TreeNode | null; right: TreeNode | null; constructor(val: number) { this.val = val; this.left = null; this.right = null; } } -> Option DQuick Check:
Correct BST node class syntax = class TreeNode { val: number; left: TreeNode | null; right: TreeNode | null; constructor(val: number) { this.val = val; this.left = null; this.right = null; } } [OK]
- Using string type for node value
- Not initializing left and right to null
- Using JavaScript function instead of TypeScript class
5 / \ 3 7 / \ 2 8Function uses in-order traversal and a set to find pairs.
Solution
Step 1: Traverse BST in-order and check pairs
In-order traversal gives sorted values: [2, 3, 5, 7, 8]. We check if target - current value exists in set.Step 2: Find pair summing to 9
Check pairs: 2 + 7 = 9 (found), so function returns true.Final Answer:
true -> Option AQuick Check:
2 + 7 = 9 found in BST [OK]
- Assuming no pair without checking all nodes
- Confusing traversal order
- Ignoring set lookup for complements
function findTarget(root: TreeNode | null, k: number): boolean {
const set = new Set<number>();
function dfs(node: TreeNode | null): boolean {
if (!node) return false;
if (set.has(k - node.val)) return true;
set.add(node.val);
dfs(node.left);
dfs(node.right);
return false;
}
return dfs(root);
}Solution
Step 1: Analyze recursive calls and return values
The dfs function calls dfs(node.left) and dfs(node.right) but ignores their return values, always returning false at the end.Step 2: Identify missing return propagation
If dfs(node.left) or dfs(node.right) returns true, dfs should return true immediately to propagate the success.Final Answer:
The function returns false too early, missing true from recursive calls -> Option CQuick Check:
Return recursive true results to avoid missing pairs [OK]
- Ignoring return values of recursive calls
- Returning false before checking all nodes
- Misunderstanding base case return
Solution
Step 1: Understand space and time constraints
We want to reduce time complexity and keep space to O(h), where h is tree height.Step 2: Evaluate approaches
Use two pointers with iterative in-order and reverse in-order traversals simultaneously uses two pointers with iterative in-order (smallest to largest) and reverse in-order (largest to smallest) traversals, allowing pair search in O(n) time and O(h) space. Other options use extra space O(n) or nested loops with O(n^2) time.Final Answer:
Use two pointers with iterative in-order and reverse in-order traversals simultaneously -> Option AQuick Check:
Two pointer BST traversal = O(n) time, O(h) space [OK]
- Using nested loops causing O(n^2) time
- Storing all nodes in list increasing space to O(n)
- Using BFS which uses more space than O(h)
Ready to prove it?
Pass the test and this pattern moves unknown
