Given two binary search trees, root1
and root2
, return true
if and only if there is a node in the first tree and a node in the second tree whose values sum up to a given integer target
.
Example 1:
Input: root1 = [2,1,4], root2 = [1,0,3], target = 5 Output: true Explanation: 2 + 3 = 5.
Example 2:
Input: root1 = [0,-10,10], root2 = [5,1,7,0,2], target = 18 Output: false
Constraints:
[1, 5000]
.-104 <= Node.val <= 104
target
is an integer in the range [-105, 105]
.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method to solve this problem is to check every single possible pair of numbers, one from each tree. We want to see if any of those pairs add up to our target value. This guarantees we will find the answer if it exists, but it might take a very long time.
Here's how the algorithm would work step-by-step:
def two_sum_bsts_brute_force(root_one, root_two, target_value):
# Convert BST one to a list
first_tree_values = []
def inorder_traversal_one(node):
if node:
inorder_traversal_one(node.left)
first_tree_values.append(node.val)
inorder_traversal_one(node.right)
inorder_traversal_one(root_one)
# Convert BST two to a list
second_tree_values = []
def inorder_traversal_two(node):
if node:
inorder_traversal_two(node.left)
second_tree_values.append(node.val)
inorder_traversal_two(node.right)
inorder_traversal_two(root_two)
# Iterate through all possible pairs
for first_tree_value in first_tree_values:
# Check every node in the second tree.
for second_tree_value in second_tree_values:
# We found our match
if first_tree_value + second_tree_value == target_value:
return True
# If no pair sums to the target, return False
return False
The problem asks us to find if there's a pair of numbers, one from each of two special trees, that add up to a target value. The best way to solve this efficiently is to change one of the trees into an easy-to-search structure, then quickly check if the complement of each value in the other tree exists in this searchable structure.
Here's how the algorithm would work step-by-step:
def find_target_in_two_bsts(root1, root2, target_value):
# Convert the first BST into a set for fast lookups.
tree1_values = set()
def inorder_traversal_tree1(node):
if node:
inorder_traversal_tree1(node.left)
tree1_values.add(node.val)
inorder_traversal_tree1(node.right)
inorder_traversal_tree1(root1)
def inorder_traversal_tree2(node):
if node:
# Explore the left subtree
inorder_traversal_tree2(node.left)
# Calculate the complement needed from the first tree.
complement = target_value - node.val
# Check if the complement exists in the set from tree1.
if complement in tree1_values:
return True
# Explore the right subtree
if inorder_traversal_tree2(node.right):
return True
return False
# Initiate the search on the second tree, given the set of the first tree
return inorder_traversal_tree2(root2)
Case | How to Handle |
---|---|
Both BSTs are null | Return false immediately, as no sum can be found. |
One BST is null, the other is not | Return false immediately, as we need nodes from both trees. |
One or both BSTs contain duplicate values. | The in-order traversal and lookup in the other BST will still work correctly because we are looking for existence of a target value. |
Target value is very large (potential overflow during sum calculation) | Use a long data type or appropriate overflow checks to handle potentially large target values. |
No pair of nodes sums to the target value | The algorithm should complete the search and return false after exhausting all possibilities. |
The BSTs are highly unbalanced, resulting in worst-case traversal time. | Consider balancing BSTs to guarantee O(n) traversal if modifications are allowed, or accept O(n*h) time complexity where h is the height. |
Extremely large BSTs that might exceed memory limits when converting to a sorted array. | Use an iterative in-order traversal with a stack to avoid creating large arrays and reduce memory usage. |
BSTs contain negative numbers and zero. | The in-order traversal and subsequent target value search in the second BST handles negative numbers and zero correctly. |