[Naive Approach] By Trying all Possible Pairs - O(n1 * n2) Time and O(h1 + h2) Space
The idea is to traverse the first BST. For each node, search for the value (x - node) in the second BST. If the value exists, increment the count.
C++
//Driver Code Starts#include<iostream>usingnamespacestd;// Node structureclassNode{public:intdata;Node*left,*right;Node(intx){data=x;left=nullptr;right=nullptr;}};//Driver Code Ends// Search for (x-node value) in second bstboolfindVal(Node*root,intx){if(root==nullptr)returnfalse;if(root->data==x)returntrue;elseif(root->data<x)returnfindVal(root->right,x);elsereturnfindVal(root->left,x);}// Function to count pairs with sum equal to xintcountPairs(Node*root1,Node*root2,intx){if(root1==nullptr)return0;intans=0;// If pair (root1.data, x-root1.data) exists,// then increment the ans.if(findVal(root2,x-root1->data))ans++;// Recursively check for left and right subtree. ans+=countPairs(root1->left,root2,x);ans+=countPairs(root1->right,root2,x);returnans;}//Driver Code Startsintmain(){// BST1// 2// / \ // 1 3Node*root1=newNode(2);root1->left=newNode(1);root1->right=newNode(3);// BST2// 5// / \ // 4 6Node*root2=newNode(5);root2->left=newNode(4);root2->right=newNode(6);intx=6;cout<<countPairs(root1,root2,x);return0;}//Driver Code Ends
Java
//Driver Code Starts// Node structureclassNode{intdata;Nodeleft,right;Node(intx){data=x;left=null;right=null;}}classGfG{//Driver Code Ends// Search for (x-node value) in second bststaticbooleanfindVal(Noderoot,intx){if(root==null)returnfalse;if(root.data==x)returntrue;elseif(root.data<x)returnfindVal(root.right,x);elsereturnfindVal(root.left,x);}// Function to count pairs with sum equal to xstaticintcountPairs(Noderoot1,Noderoot2,intx){if(root1==null)return0;intans=0;// If pair (root1.data, x-root1.data) exists,// then increment the ans.if(findVal(root2,x-root1.data))ans++;// Recursively check for left and right subtree.ans+=countPairs(root1.left,root2,x);ans+=countPairs(root1.right,root2,x);returnans;}//Driver Code Startspublicstaticvoidmain(String[]args){// BST1// 2// / \// 1 3Noderoot1=newNode(2);root1.left=newNode(1);root1.right=newNode(3);// BST2// 5// / \// 4 6Noderoot2=newNode(5);root2.left=newNode(4);root2.right=newNode(6);intx=6;System.out.println(countPairs(root1,root2,x));}}//Driver Code Ends
Python
#Driver Code Starts# Node structureclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=None#Driver Code Ends# Search for (x-node value) in second bstdeffindVal(root,x):ifrootisNone:returnFalseifroot.data==x:returnTrueelifroot.data<x:returnfindVal(root.right,x)else:returnfindVal(root.left,x)# Function to count pairs with sum equal to xdefcountPairs(root1,root2,x):ifroot1isNone:return0ans=0# If pair (root1.data, x-root1.data) exists,# then increment the ans.iffindVal(root2,x-root1.data):ans+=1# Recursively check for left and right subtree.ans+=countPairs(root1.left,root2,x)ans+=countPairs(root1.right,root2,x)returnans#Driver Code Startsif__name__=="__main__":# BST1# 2# / \# 1 3root1=Node(2)root1.left=Node(1)root1.right=Node(3)# BST2# 5# / \# 4 6root2=Node(5)root2.left=Node(4)root2.right=Node(6)x=6print(countPairs(root1,root2,x))#Driver Code Ends
C#
//Driver Code StartsusingSystem;// Node structureclassNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=null;right=null;}}classGfG{//Driver Code Ends// Search for (x-node value) in second bststaticboolfindVal(Noderoot,intx){if(root==null)returnfalse;if(root.data==x)returntrue;elseif(root.data<x)returnfindVal(root.right,x);elsereturnfindVal(root.left,x);}// Function to count pairs with sum equal to xstaticintcountPairs(Noderoot1,Noderoot2,intx){if(root1==null)return0;intans=0;// If pair (root1.data, x-root1.data) exists,// then increment the ans.if(findVal(root2,x-root1.data))ans++;// Recursively check for left and // right subtree.ans+=countPairs(root1.left,root2,x);ans+=countPairs(root1.right,root2,x);returnans;}//Driver Code StartsstaticvoidMain(string[]args){// BST1// 2// / \// 1 3Noderoot1=newNode(2);root1.left=newNode(1);root1.right=newNode(3);// BST2// 5// / \// 4 6Noderoot2=newNode(5);root2.left=newNode(4);root2.right=newNode(6);intx=6;Console.WriteLine(countPairs(root1,root2,x));}}//Driver Code Ends
JavaScript
//Driver Code Starts// Node structureclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}//Driver Code Ends// Search for (x-node value) in second bstfunctionfindVal(root,x){if(root===null)returnfalse;if(root.data===x)returntrue;elseif(root.data<x)returnfindVal(root.right,x);elsereturnfindVal(root.left,x);}// Function to count pairs with // sum equal to xfunctioncountPairs(root1,root2,x){if(root1===null)return0;letans=0;// If pair (root1.data, x-root1.data) exists,// then increment the ans.if(findVal(root2,x-root1.data))ans++;// Recursively check for left and right subtree.ans+=countPairs(root1.left,root2,x);ans+=countPairs(root1.right,root2,x);returnans;}//Driver Code Starts// Driver Code// BST1// 2// / \// 1 3letroot1=newNode(2);root1.left=newNode(1);root1.right=newNode(3);// BST2// 5// / \// 4 6letroot2=newNode(5);root2.left=newNode(4);root2.right=newNode(6);letx=6;console.log(countPairs(root1,root2,x));//Driver Code Ends
Output
2
[Expected Approach] Two Pointer Technique - O(n1 + n2) Time and O(h1 + h2) Space
Intuition: If we are given a sorted array and asked to find pairs whose sum is equal to x, we often use the two-pointer technique. One pointer starts from the beginning (smallest value), while the other starts from the end (largest value). We can apply the same concept to two BSTs.
The inorder traversal of a BST gives nodes in sorted ascending order and reverse inorder traversal gives nodes in sorted descending order.
So, if we traverse the first BST in inorder (gives the smallest value first) and second BST in reverse inorder (gives the largest value first).
It becomes exactly like having two sorted arrays and applying the two-pointer technique to find pairs that sum up to x.
The idea is to use the two-pointer technique with stacks on BSTs. One stack does inorder traversal of the first BST (ascending), the other does reverse inorder traversal of the second BST (descending). At each step, check the sum of the top elements: if it equals x, we found a pair; if greater, move left in the second BST; if smaller, move right in the first BST.
C++
//Driver Code Starts#include<iostream>#include<stack>#include<algorithm>usingnamespacestd;// Node structureclassNode{public:intdata;Node*left,*right;Node(intx){data=x;left=nullptr;right=nullptr;}};//Driver Code EndsintcountPairs(Node*root1,Node*root2,intx){if(root1==nullptr||root2==nullptr)return0;stack<Node*>st1,st2;Node*top1,*top2;intcount=0;while(1){// to find next node in inorder// traversal of BST 1while(root1!=nullptr){st1.push(root1);root1=root1->left;}// to find next node in reverse// inorder traversal of BST 2while(root2!=nullptr){st2.push(root2);root2=root2->right;}if(st1.empty()||st2.empty())break;top1=st1.top();top2=st2.top();// if the sum of the node's is equal to 'x'if((top1->data+top2->data)==x){count++;st1.pop();st2.pop();// insert next possible node in the// respective stacksroot1=top1->right;root2=top2->left;}// move to next possible node in the// inorder traversal of BST 1elseif((top1->data+top2->data)<x){st1.pop();root1=top1->right;}// move to next possible node in the// reverse inorder traversal of BST 2else{st2.pop();root2=top2->left;}}returncount;}//Driver Code Startsintmain(){// BST1// 2// / \ // 1 3Node*root1=newNode(2);root1->left=newNode(1);root1->right=newNode(3);// BST2// 5// / \ // 4 6Node*root2=newNode(5);root2->left=newNode(4);root2->right=newNode(6);intx=6;cout<<countPairs(root1,root2,x);return0;}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.Stack;// Node structureclassNode{intdata;Nodeleft,right;Node(intx){data=x;left=null;right=null;}}classGfG{//Driver Code EndsstaticintcountPairs(Noderoot1,Noderoot2,intx){if(root1==null||root2==null)return0;Stack<Node>st1=newStack<>();Stack<Node>st2=newStack<>();Nodetop1,top2;intcount=0;while(true){// to find next node in inorder// traversal of BST 1while(root1!=null){st1.push(root1);root1=root1.left;}// to find next node in reverse// inorder traversal of BST 2while(root2!=null){st2.push(root2);root2=root2.right;}if(st1.isEmpty()||st2.isEmpty())break;top1=st1.peek();top2=st2.peek();// if the sum of the node's is equal to 'x'if((top1.data+top2.data)==x){count++;st1.pop();st2.pop();// insert next possible node in the// respective stacksroot1=top1.right;root2=top2.left;}// move to next possible node in the// inorder traversal of BST 1elseif((top1.data+top2.data)<x){st1.pop();root1=top1.right;}// move to next possible node in the// reverse inorder traversal of BST 2else{st2.pop();root2=top2.left;}}returncount;}//Driver Code Startspublicstaticvoidmain(String[]args){// BST1// 2// / \// 1 3Noderoot1=newNode(2);root1.left=newNode(1);root1.right=newNode(3);// BST2// 5// / \// 4 6Noderoot2=newNode(5);root2.left=newNode(4);root2.right=newNode(6);intx=6;System.out.println(countPairs(root1,root2,x));}}//Driver Code Ends
Python
#Driver Code Starts# Node structureclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=None#Driver Code EndsdefcountPairs(root1,root2,x):ifroot1isNoneorroot2isNone:return0st1,st2=[],[]count=0whileTrue:# to find next node in inorder# traversal of BST 1whileroot1isnotNone:st1.append(root1)root1=root1.left# to find next node in reverse# inorder traversal of BST 2whileroot2isnotNone:st2.append(root2)root2=root2.rightifnotst1ornotst2:breaktop1=st1[-1]top2=st2[-1]# if the sum of the node's is equal to 'x'if(top1.data+top2.data)==x:count+=1st1.pop()st2.pop()# insert next possible node in the# respective stacksroot1=top1.rightroot2=top2.left# move to next possible node in the# inorder traversal of BST 1elif(top1.data+top2.data)<x:st1.pop()root1=top1.right# move to next possible node in the# reverse inorder traversal of BST 2else:st2.pop()root2=top2.leftreturncount#Driver Code Startsif__name__=="__main__":# BST1# 2# / \# 1 3root1=Node(2)root1.left=Node(1)root1.right=Node(3)# BST2# 5# / \# 4 6root2=Node(5)root2.left=Node(4)root2.right=Node(6)x=6print(countPairs(root1,root2,x))#Driver Code Ends
C#
//Driver Code StartsusingSystem;usingSystem.Collections.Generic;// Node structureclassNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=null;right=null;}}classGfG{//Driver Code EndsstaticintcountPairs(Noderoot1,Noderoot2,intx){if(root1==null||root2==null)return0;Stack<Node>st1=newStack<Node>();Stack<Node>st2=newStack<Node>();Nodetop1,top2;intcount=0;while(true){// to find next node in inorder// traversal of BST 1while(root1!=null){st1.Push(root1);root1=root1.left;}// to find next node in reverse// inorder traversal of BST 2while(root2!=null){st2.Push(root2);root2=root2.right;}if(st1.Count==0||st2.Count==0)break;top1=st1.Peek();top2=st2.Peek();// if the sum of the node's is // equal to 'x'if((top1.data+top2.data)==x){count++;st1.Pop();st2.Pop();// insert next possible node in the// respective stacksroot1=top1.right;root2=top2.left;}// move to next possible node in the// inorder traversal of BST 1elseif((top1.data+top2.data)<x){st1.Pop();root1=top1.right;}// move to next possible node in the// reverse inorder traversal of BST 2else{st2.Pop();root2=top2.left;}}returncount;}//Driver Code StartsstaticvoidMain(string[]args){// BST1// 2// / \// 1 3Noderoot1=newNode(2);root1.left=newNode(1);root1.right=newNode(3);// BST2// 5// / \// 4 6Noderoot2=newNode(5);root2.left=newNode(4);root2.right=newNode(6);intx=6;Console.WriteLine(countPairs(root1,root2,x));}}//Driver Code Ends
JavaScript
//Driver Code Starts// Node structureclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}//Driver Code EndsfunctioncountPairs(root1,root2,x){if(root1===null||root2===null)return0;letst1=[],st2=[];lettop1,top2;letcount=0;while(true){// to find next node in inorder// traversal of BST 1while(root1!==null){st1.push(root1);root1=root1.left;}// to find next node in reverse// inorder traversal of BST 2while(root2!==null){st2.push(root2);root2=root2.right;}if(st1.length===0||st2.length===0)break;top1=st1[st1.length-1];top2=st2[st2.length-1];// if the sum of the node's is equal to 'x'if((top1.data+top2.data)===x){count++;st1.pop();st2.pop();// insert next possible node in the// respective stacksroot1=top1.right;root2=top2.left;}// move to next possible node in the// inorder traversal of BST 1elseif((top1.data+top2.data)<x){st1.pop();root1=top1.right;}// move to next possible node in the// reverse inorder traversal of BST 2else{st2.pop();root2=top2.left;}}returncount;}//Driver Code Starts// Driver Code// BST1// 2// / \// 1 3letroot1=newNode(2);root1.left=newNode(1);root1.right=newNode(3);// BST2// 5// / \// 4 6letroot2=newNode(5);root2.left=newNode(4);root2.right=newNode(6);letx=6;console.log(countPairs(root1,root2,x));//Driver Code Ends