Given the root of a Binary Search Tree (BST) of size n and an integer target, determine whether there exists a pair of distinct nodes in the BST such that the sum of their values is equal to the given target. Return true if such a pair exists; otherwise, return false.
Example:
Input: root = [7, 3, 8, 2, 4, N, 9], target = 12 Output: true Explanation: In the given binary tree, there are two nodes (3 and 9) that add up to 12.
Input: root = [9, 5, 10, 2, 6, N, 12], target = 23 Output: false Explanation: In the given binary tree, there are no such two nodes that add up to 23.
[Naive Approach] Check Complement for Every Node - O(n²) Time and O(h) Space
The idea is to traverse the BST and, for each node, search for its complement (target - node value) in the BST. If the complement exists in a different node, return true.
C++
#include<iostream>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intd){data=d;left=nullptr;right=nullptr;}};// Function to search for the Key in the BSTboolsearch(Node*root,intkey,Node*temp){// If the root is NULL, return falseif(root==nullptr)returnfalse;// Start search from the rootNode*current=root;// Traverse the BST to find the target value `k`while(current!=nullptr){// If Key is foundif(current->data==key&¤t!=temp)returntrue;// If key is smaller, move to the leftelseif(key<current->data)current=current->left;// If key is larger, move to the rightelsecurrent=current->right;}// Return false if no match is foundreturnfalse;}// Helper Function to find if there exists a pair // with a given sum in the BSTboolfindTargetRec(Node*root,Node*current,inttarget){if(current==nullptr)returnfalse;// Check if the complement of the current node value existsintcomplement=target-current->data;if(search(root,complement,current))returntrue;// Check for the pair in left and right subtreereturnfindTargetRec(root,current->left,target)||findTargetRec(root,current->right,target);}// Function to find if there exists a pair // with a given sum in the BSTboolfindTarget(Node*root,inttarget){returnfindTargetRec(root,root,target);}intmain(){// Constructing the following BST:// 7// / \ // 3 8// / \ \ // 2 4 9Node*root=newNode(7);root->left=newNode(3);root->right=newNode(8);root->left->left=newNode(2);root->left->right=newNode(4);root->right->right=newNode(9);inttarget=12;cout<<(findTarget(root,target)?"true":"false");return0;}
Java
classNode{intdata;Nodeleft,right;Node(intd){data=d;left=right=null;}}classGfG{// Function to search for the Key in the BSTstaticbooleansearch(Noderoot,intkey,Nodetemp){// If the root is NULL, return falseif(root==null)returnfalse;// Start search from the rootNodecurrent=root;// Traverse the BST to find the target value `key`while(current!=null){// If Key is foundif(current.data==key&¤t!=temp)returntrue;// If key is smaller, move to the leftelseif(key<current.data)current=current.left;// If key is larger, move to the rightelsecurrent=current.right;}// Return false if no match is foundreturnfalse;}// Helper Function to find if there exists a pair // with a given sum in the BSTstaticbooleanfindTargetRec(Noderoot,Nodecurrent,inttarget){if(current==null)returnfalse;// Check if the complement of the current node value existsintcomplement=target-current.data;if(search(root,complement,current))returntrue;// Check for the pair in left and right subtreereturnfindTargetRec(root,current.left,target)||findTargetRec(root,current.right,target);}// Function to find if there exists a pair // with a given sum in the BSTstaticbooleanfindTarget(Noderoot,inttarget){returnfindTargetRec(root,root,target);}publicstaticvoidmain(String[]args){// Constructing the following BST:// 7// / \// 3 8// / \ \// 2 4 9Noderoot=newNode(7);root.left=newNode(3);root.right=newNode(8);root.left.left=newNode(2);root.left.right=newNode(4);root.right.right=newNode(9);inttarget=12;System.out.println(findTarget(root,target)?"true":"false");}}
Python
classNode:def__init__(self,data):self.data=dataself.left=Noneself.right=None# Function to search for the Key in the BSTdefsearch(root,key,temp):# If the root is NULL, return falseifrootisNone:returnFalse# Start search from the rootcurrent=root# Traverse the BST to find the target value `key`whilecurrent:# If Key is foundifcurrent.data==keyandcurrent!=temp:returnTrue# If key is smaller, move to the leftelifkey<current.data:current=current.left# If key is larger, move to the rightelse:current=current.right# Return false if no match is foundreturnFalse# Helper Function to find if there exists a pair # with a given sum in the BSTdeffindTargetRec(root,current,target):ifcurrentisNone:returnFalse# Check if the complement of the current node value existscomplement=target-current.dataifsearch(root,complement,current):returnTrue# Check for the pair in left and right subtreereturnfindTargetRec(root,current.left,target)or \
findTargetRec(root,current.right,target)# Function to find if there exists a pair # with a given sum in the BSTdeffindTarget(root,target):returnfindTargetRec(root,root,target)if__name__=="__main__":# Constructing the following BST:# 7# / \# 3 8# / \ \# 2 4 9root=Node(7)root.left=Node(3)root.right=Node(8)root.left.left=Node(2)root.left.right=Node(4)root.right.right=Node(9)target=12print("true"iffindTarget(root,target)else"false")
C#
usingSystem;classNode{publicintdata;publicNodeleft,right;publicNode(intd){data=d;left=right=null;}}classGfG{// Function to search for the Key in the BSTstaticboolSearch(Noderoot,intkey,Nodetemp){// If the root is NULL, return falseif(root==null)returnfalse;// Start search from the rootNodecurrent=root;// Traverse the BST to find the target value `key`while(current!=null){// If Key is foundif(current.data==key&¤t!=temp)returntrue;// If key is smaller, move to the leftelseif(key<current.data)current=current.left;// If key is larger, move to the rightelsecurrent=current.right;}// Return false if no match is foundreturnfalse;}// Helper Function to find if there exists a pair // with a given sum in the BSTstaticboolFindTargetRec(Noderoot,Nodecurrent,inttarget){if(current==null)returnfalse;// Check if the complement of the current node value existsintcomplement=target-current.data;if(Search(root,complement,current))returntrue;// Check for the pair in left and right subtreereturnFindTargetRec(root,current.left,target)||FindTargetRec(root,current.right,target);}// Function to find if there exists a pair // with a given sum in the BSTstaticboolFindTarget(Noderoot,inttarget){returnFindTargetRec(root,root,target);}staticvoidMain(string[]args){// Constructing the following BST:// 7// / \// 3 8// / \ \// 2 4 9Noderoot=newNode(7);root.left=newNode(3);root.right=newNode(8);root.left.left=newNode(2);root.left.right=newNode(4);root.right.right=newNode(9);inttarget=12;Console.WriteLine(FindTarget(root,target)?"true":"false");}}
JavaScript
classNode{constructor(data){this.data=data;this.left=null;this.right=null;}}// Function to search for the Key in the BSTfunctionsearch(root,key,temp){// If the root is NULL, return falseif(root===null)returnfalse;// Start search from the rootletcurrent=root;// Traverse the BST to find the target value `key`while(current!==null){// If Key is foundif(current.data===key&¤t!==temp)returntrue;// If key is smaller, move to the leftelseif(key<current.data)current=current.left;// If key is larger, move to the rightelsecurrent=current.right;}// Return false if no match is foundreturnfalse;}// Helper Function to find if there exists a pair // with a given sum in the BSTfunctionfindTargetRec(root,current,target){if(current===null)returnfalse;// Check if the complement of the current node value existsconstcomplement=target-current.data;if(search(root,complement,current))returntrue;// Check for the pair in left and right subtreereturnfindTargetRec(root,current.left,target)||findTargetRec(root,current.right,target);}// Function to find if there exists a pair // with a given sum in the BSTfunctionfindTarget(root,target){returnfindTargetRec(root,root,target);}// Driver Code// Constructing the following BST:// 7// / \// 3 8// / \ \// 2 4 9constroot=newNode(7);root.left=newNode(3);root.right=newNode(8);root.left.left=newNode(2);root.left.right=newNode(4);root.right.right=newNode(9);lettarget=12;console.log(findTarget(root,target)?"true":"false");
Output
true
[Better Approach 1] Using Hash Set - O(n) time and O(n) space
The idea of this approach is to use a Hash Set to store the values of nodes visited during a traversal of the BST. While traversing each node, we check whether the complement value (target - current node value) already exists in the set. If it exists, it means a valid pair of distinct nodes has been found whose sum is equal to the target, and we return true. Otherwise, we insert the current node’s value into the set and continue the traversal.
C++
//Driver Code Starts#include<iostream>#include<unordered_set>usingnamespacestd;classNode{public:intdata;Node*left,*right;Node(intx){data=x;left=nullptr;right=nullptr;}};// Helper function to perform DFS and check//Driver Code Ends// for the required target.booldfs(Node*root,unordered_set<int>&st,inttarget){if(root==nullptr)returnfalse;// Check if the complement (target - current node's value)// exists in the setif(st.find(target-root->data)!=st.end())returntrue;// Insert the current node's value into the setst.insert(root->data);// Continue the search in the left and right subtreesreturndfs(root->left,st,target)||dfs(root->right,st,target);}// Main function to check if two elements// in the BST target to targetboolfindTarget(Node*root,inttarget){// To store visited nodes' valuesunordered_set<int>st;// Start DFS from the rootreturndfs(root,st,target);}intmain(){//Driver Code Starts// Constructing the following BST:// 7// / \ // 3 8// / \ \ // 2 4 9Node*root=newNode(7);root->left=newNode(3);root->right=newNode(8);root->left->left=newNode(2);root->left->right=newNode(4);root->right->right=newNode(9);inttarget=12;if(findTarget(root,target))cout<<"true";elsecout<<"false";return0;}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.HashSet;classNode{intdata;Nodeleft,right;Node(intx){data=x;left=null;right=null;}}classGfG{// Helper function to perform DFS and check//Driver Code Ends// for the required target.staticbooleandfs(Noderoot,HashSet<Integer>set,inttarget){if(root==null)returnfalse;// Check if the complement (target - current node's value)// exists in the setif(set.contains(target-root.data))returntrue;// Insert the current node's value into the setset.add(root.data);// Continue the search in the left and right subtreesreturndfs(root.left,set,target)||dfs(root.right,set,target);}// Main function to check if two elements// in the BST target to targetstaticbooleanfindTarget(Noderoot,inttarget){HashSet<Integer>set=newHashSet<>();returndfs(root,set,target);}publicstaticvoidmain(String[]args){//Driver Code Starts// Constructing the following BST:// 7// / \// 3 8// / \ \// 2 4 9Noderoot=newNode(7);root.left=newNode(3);root.right=newNode(8);root.left.left=newNode(2);root.left.right=newNode(4);root.right.right=newNode(9);inttarget=12;if(findTarget(root,target))System.out.println("true");elseSystem.out.println("false");}}//Driver Code Ends
Python
#Driver Code StartsclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Helper function to perform DFS and check# for the required target.#Driver Code Endsdefdfs(root,st,target):ifrootisNone:returnFalse# Check if the complement (target - current node's value)# exists in the setiftarget-root.datainst:returnTrue# Insert the current node's value into the setst.add(root.data)# Continue the search in the left and right subtreesreturndfs(root.left,st,target)ordfs(root.right,st,target)# Main function to check if two elements# in the BST target to targetdeffindTarget(root,target):st=set()returndfs(root,st,target)if__name__=="__main__":# Constructing the following BST:#Driver Code Starts# 7# / \# 3 8# / \ \# 2 4 9root=Node(7)root.left=Node(3)root.right=Node(8)root.left.left=Node(2)root.left.right=Node(4)root.right.right=Node(9)target=12iffindTarget(root,target):print("true")else:print("false")#Driver Code Ends
C#
//Driver Code StartsusingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=null;right=null;}}classGfG{// Helper function to perform DFS and check//Driver Code Ends// for the required target.staticbooldfs(Noderoot,HashSet<int>set,inttarget){if(root==null)returnfalse;// Check if the complement (target - current node's value)// exists in the setif(set.Contains(target-root.data))returntrue;// Insert the current node's value into the setset.Add(root.data);// Continue the search in the left and right subtreesreturndfs(root.left,set,target)||dfs(root.right,set,target);}// Main function to check if two elements// in the BST target to targetstaticboolfindTarget(Noderoot,inttarget){HashSet<int>set=newHashSet<int>();returndfs(root,set,target);}staticvoidMain(string[]args){//Driver Code Starts// Constructing the following BST:// 7// / \// 3 8// / \ \// 2 4 9Noderoot=newNode(7);root.left=newNode(3);root.right=newNode(8);root.left.left=newNode(2);root.left.right=newNode(4);root.right.right=newNode(9);inttarget=12;if(findTarget(root,target))Console.WriteLine("true");elseConsole.WriteLine("false");}}//Driver Code Ends
JavaScript
//Driver Code StartsclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Helper function to perform DFS and check//Driver Code Ends// for the required target.functiondfs(root,set,target){if(root===null)returnfalse;// Check if the complement (target - current node's value)// exists in the setif(set.has(target-root.data))returntrue;// Insert the current node's value into the setset.add(root.data);// Continue the search in the left and right subtreesreturndfs(root.left,set,target)||dfs(root.right,set,target);}// Main function to check if two elements// in the BST target to targetfunctionfindTarget(root,target){constset=newSet();returndfs(root,set,target);}// Driver Code//Driver Code Starts// Constructing the following BST:// 7// / \// 3 8// / \ \// 2 4 9constroot=newNode(7);root.left=newNode(3);root.right=newNode(8);root.left.left=newNode(2);root.left.right=newNode(4);root.right.right=newNode(9);consttarget=12;if(findTarget(root,target)){console.log("true");}else{console.log("false");}//Driver Code Ends
Output
true
[Expected Approach 2] Using Inorder Traversal and Two Pointers - O(n) time and O(n) space
The idea of this approach is based on the property of a Binary Search Tree (BST), where an inorder traversal always produces elements in sorted order. We first perform an inorder traversal of the BST and store all node values in an auxiliary array. Since the BST inorder is sorted, the resulting array will also be sorted. Once we have the sorted array, we apply the two-pointer technique to find whether there exists a pair of elements whose sum is equal to the given target.
Perform inorder traversal of the BST
Store all node values in an array, which becomes sorted due to BST inorder property
Initialize two pointers: left = 0 and right = n - 1
While left < right, compute currentSum = arr[left] + arr[right]
If currentSum == target, return true
If currentSum < target, increment left pointer
If currentSum > target, decrement right pointer
If no valid pair is found after traversal, return false
Consider the BST: root = [7, 3, 8, 2, 4, N, 9], target = 12
left = 0 (2), right = 5 (9): sum = 11 -> less than 12 -> move left++
left = 1 (3), right = 5 (9): sum = 12 -> equal to target -> return true
Final Result: Pair found: (3, 9), hence, we return true.
C++
//Driver Code Starts#include<iostream>#include<vector>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intd){data=d;left=nullptr;right=nullptr;}};// Function to perform Inorder traversal and store the //Driver Code Ends// elements in a vectorvoidinorderTraversal(Node*root,vector<int>&inorder){if(root==nullptr)return;inorderTraversal(root->left,inorder);// Store the current node's valueinorder.push_back(root->data);inorderTraversal(root->right,inorder);}boolfindTarget(Node*root,inttarget){// Create an auxiliary array and store Inorder traversalvector<int>inorder;inorderTraversal(root,inorder);// Use two-pointer technique to find the pair with given sumintleft=0,right=inorder.size()-1;while(left<right){intcurrentSum=inorder[left]+inorder[right];// If the pair is found, return trueif(currentSum==target)returntrue;// If the current sum is less than the target, // move the left pointerif(currentSum<target)left++;// If the current sum is greater than // the target, move the right pointerelseright--;}returnfalse;}intmain(){// Constructing the following BST:// 7//Driver Code Starts// / \ // 3 8// / \ \ // 2 4 9Node*root=newNode(7);root->left=newNode(3);root->right=newNode(8);root->left->left=newNode(2);root->left->right=newNode(4);root->right->right=newNode(9);inttarget=12;if(findTarget(root,target))cout<<"true";elsecout<<"false";return0;}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.ArrayList;classNode{intdata;Nodeleft,right;Node(intdata){this.data=data;left=null;right=null;}}classGfG{// Function to perform Inorder traversal and store the // elements in an array//Driver Code EndsstaticvoidinorderTraversal(Noderoot,ArrayList<Integer>inorder){if(root==null)return;inorderTraversal(root.left,inorder);// Store the current node's valueinorder.add(root.data);inorderTraversal(root.right,inorder);}staticbooleanfindTarget(Noderoot,inttarget){// Create an auxiliary array and store Inorder traversalArrayList<Integer>inorder=newArrayList<>();inorderTraversal(root,inorder);// Use two-pointer technique to find the pair with given sumintleft=0,right=inorder.size()-1;while(left<right){intcurrentSum=inorder.get(left)+inorder.get(right);// If the pair is found, return trueif(currentSum==target)returntrue;// If the current sum is less than the target, // move the left pointerif(currentSum<target)left++;// If the current sum is greater than // the target, move the right pointerelseright--;}returnfalse;}publicstaticvoidmain(String[]args){// Constructing the following BST:// 7// / \//Driver Code Starts// 3 8// / \ \// 2 4 9Noderoot=newNode(7);root.left=newNode(3);root.right=newNode(8);root.left.left=newNode(2);root.left.right=newNode(4);root.right.right=newNode(9);inttarget=12;if(findTarget(root,target))System.out.println("true");elseSystem.out.println("false");}}//Driver Code Ends
Python
#Driver Code StartsclassNode:def__init__(self,data):self.data=dataself.left=Noneself.right=None# Function to perform Inorder traversal and store the # elements in an array#Driver Code EndsdefinorderTraversal(root,inorder):ifrootisNone:returninorderTraversal(root.left,inorder)# Store the current node's valueinorder.append(root.data)inorderTraversal(root.right,inorder)deffindTarget(root,target):# Create an auxiliary array and store Inorder traversalinorder=[]inorderTraversal(root,inorder)# Use two-pointer technique to find the pair with given sumleft,right=0,len(inorder)-1whileleft<right:currentSum=inorder[left]+inorder[right]# If the pair is found, return trueifcurrentSum==target:returnTrue# If the current sum is less than the target, # move the left pointerifcurrentSum<target:left+=1# If the current sum is greater than # the target, move the right pointerelse:right-=1returnFalseif__name__=="__main__":# Constructing the following BST:# 7#Driver Code Starts# / \# 3 8# / \ \# 2 4 9root=Node(7)root.left=Node(3)root.right=Node(8)root.left.left=Node(2)root.left.right=Node(4)root.right.right=Node(9)target=12iffindTarget(root,target):print("true")else:print("false")#Driver Code Ends
C#
//Driver Code StartsusingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft,right;publicNode(intdata){this.data=data;left=right=null;}}classGfG{// Function to perform Inorder traversal and store the // elements in a list//Driver Code EndsstaticvoidinorderTraversal(Noderoot,List<int>inorder){if(root==null)return;inorderTraversal(root.left,inorder);// Store the current node's valueinorder.Add(root.data);inorderTraversal(root.right,inorder);}staticboolfindTarget(Noderoot,inttarget){// Create an auxiliary list and store Inorder traversalList<int>inorder=newList<int>();inorderTraversal(root,inorder);// Use two-pointer technique to find the pair with given sumintleft=0,right=inorder.Count-1;while(left<right){intcurrentSum=inorder[left]+inorder[right];// If the pair is found, return trueif(currentSum==target)returntrue;// If the current sum is less than the target, // move the left pointerif(currentSum<target)left++;// If the current sum is greater than // the target, move the right pointerelseright--;}returnfalse;}staticvoidMain(string[]args){// Constructing the following BST:// 7// / \//Driver Code Starts// 3 8// / \ \// 2 4 9Noderoot=newNode(7);root.left=newNode(3);root.right=newNode(8);root.left.left=newNode(2);root.left.right=newNode(4);root.right.right=newNode(9);inttarget=12;if(findTarget(root,target))Console.WriteLine("true");elseConsole.WriteLine("false");}}//Driver Code Ends
JavaScript
//Driver Code StartsclassNode{constructor(data){this.data=data;this.left=null;this.right=null;}}// Function to perform Inorder traversal and store the // elements in an array//Driver Code EndsfunctioninorderTraversal(root,inorder){if(root===null)return;inorderTraversal(root.left,inorder);// Store the current node's valueinorder.push(root.data);inorderTraversal(root.right,inorder);}functionfindTarget(root,target){// Create an auxiliary array and store Inorder traversalletinorder=[];inorderTraversal(root,inorder);// Use two-pointer technique to find the pair with given sumletleft=0,right=inorder.length-1;while(left<right){letcurrentSum=inorder[left]+inorder[right];// If the pair is found, return trueif(currentSum===target)returntrue;// If the current sum is less than the target, // move the left pointerif(currentSum<target)left++;// If the current sum is greater than // the target, move the right pointerelseright--;}returnfalse;}// Driver Code// Constructing the following BST:// 7// / \//Driver Code Starts// 3 8// / \ \// 2 4 9constroot=newNode(7);root.left=newNode(3);root.right=newNode(8);root.left.left=newNode(2);root.left.right=newNode(4);root.right.right=newNode(9);consttarget=12;if(findTarget(root,target)){console.log("true");}else{console.log("false");}//Driver Code Ends