Given the roots r1 and r2 of two Binary Search Trees (BSTs), find all node values that are present in both trees. Return the common node values in sorted order.
Example:
Input: r1 = [5, 1, 10, 0, 4, 7, N, N, N, N, N, N, 9], r2 = [10, 7, 20, 4, 9, N, N]
Output: [4, 7, 9, 10] Explanation: The nodes 4, 7, 9, and 10 are present in both BSTs.
[Naive Approach] Using Inorder Traversal with BST Search - O(n × h) Time and O(h) Space
The idea is to traverse the first BST in inorder so that the nodes are visited in sorted order. For every node encountered, search for the same value in the second BST using the BST search operation.
If the value is found in the second BST, add it to the result. Since the first BST is traversed in inorder, the common nodes are automatically collected in sorted order.
C++
#include<iostream>#include<vector>usingnamespacestd;// Structure of a BST node.classNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=right=nullptr;}};// Insert a node into the BST.Node*insert(Node*root,intkey){if(!root)returnnewNode(key);if(key<root->data)root->left=insert(root->left,key);elseroot->right=insert(root->right,key);returnroot;}// Search for a key in the BST.boolsearch(Node*root,intkey){if(!root)returnfalse;if(root->data==key)returntrue;if(key<root->data)returnsearch(root->left,key);returnsearch(root->right,key);}// Traverse the first BST in inorder.voidinorder(Node*root,Node*r2,vector<int>&res){if(!root)return;inorder(root->left,r2,res);if(search(r2,root->data))res.push_back(root->data);inorder(root->right,r2,res);}// Function to return the common nodes of two BSTs.vector<int>findCommon(Node*r1,Node*r2){vector<int>res;inorder(r1,r2,res);returnres;}intmain(){// First BST//// 5// / \ // 1 10// / \ /// 0 4 7// \ // 9//Node*r1=nullptr;r1=insert(r1,5);r1=insert(r1,1);r1=insert(r1,10);r1=insert(r1,0);r1=insert(r1,4);r1=insert(r1,7);r1=insert(r1,9);// Second BST//// 10// / \ // 7 20// / \ // 4 9//Node*r2=nullptr;r2=insert(r2,10);r2=insert(r2,7);r2=insert(r2,20);r2=insert(r2,4);r2=insert(r2,9);vector<int>res=findCommon(r1,r2);// Print the array.cout<<"[";for(inti=0;i<res.size();i++){cout<<res[i];if(i!=res.size()-1)cout<<", ";}cout<<"]";return0;}
Java
importjava.util.*;// Structure of a BST node.classNode{intdata;Nodeleft;Noderight;Node(intval){data=val;left=right=null;}}publicclassGFG{// Insert a node into the BST.staticNodeinsert(Noderoot,intkey){if(root==null)returnnewNode(key);if(key<root.data)root.left=insert(root.left,key);elseroot.right=insert(root.right,key);returnroot;}// Search for a key in the BST.staticbooleansearch(Noderoot,intkey){if(root==null)returnfalse;if(root.data==key)returntrue;if(key<root.data)returnsearch(root.left,key);returnsearch(root.right,key);}// Traverse the first BST in inorder.staticvoidinorder(Noderoot,Noder2,ArrayList<Integer>res){if(root==null)return;inorder(root.left,r2,res);if(search(r2,root.data))res.add(root.data);inorder(root.right,r2,res);}// Function to return the common nodes of two BSTs.staticArrayList<Integer>findCommon(Noder1,Noder2){ArrayList<Integer>res=newArrayList<>();inorder(r1,r2,res);returnres;}publicstaticvoidmain(String[]args){// First BST//// 5// / \// 1 10// / \ /// 0 4 7// \// 9//Noder1=null;r1=insert(r1,5);r1=insert(r1,1);r1=insert(r1,10);r1=insert(r1,0);r1=insert(r1,4);r1=insert(r1,7);r1=insert(r1,9);// Second BST//// 10// / \// 7 20// / \// 4 9//Noder2=null;r2=insert(r2,10);r2=insert(r2,7);r2=insert(r2,20);r2=insert(r2,4);r2=insert(r2,9);ArrayList<Integer>res=findCommon(r1,r2);// Print the array.System.out.print("[");for(inti=0;i<res.size();i++){System.out.print(res.get(i));if(i!=res.size()-1)System.out.print(", ");}System.out.print("]");}}
Python
# Structure of a BST node.classNode:def__init__(self,val):self.data=valself.left=Noneself.right=None# Insert a node into the BST.definsert(root:'Node',key:int)->'Node':ifnotroot:returnNode(key)ifkey<root.data:root.left=insert(root.left,key)else:root.right=insert(root.right,key)returnroot# Search for a key in the BST.defsearch(root:'Node',key:int)->bool:ifnotroot:returnFalseifroot.data==key:returnTrueifkey<root.data:returnsearch(root.left,key)returnsearch(root.right,key)# Traverse the first BST in inorder.definorder(root:'Node',r2:'Node',res:list[int])->None:ifnotroot:returninorder(root.left,r2,res)ifsearch(r2,root.data):res.append(root.data)inorder(root.right,r2,res)# Function to return the common nodes of two BSTs.deffindCommon(r1:'Node',r2:'Node')->list[int]:res=[]inorder(r1,r2,res)returnresdefmain():# First BST## 5# / \# 1 10# / \ /# 0 4 7# \# 9#r1=Noner1=insert(r1,5)r1=insert(r1,1)r1=insert(r1,10)r1=insert(r1,0)r1=insert(r1,4)r1=insert(r1,7)r1=insert(r1,9)# Second BST## 10# / \# 7 20# / \# 4 9#r2=Noner2=insert(r2,10)r2=insert(r2,7)r2=insert(r2,20)r2=insert(r2,4)r2=insert(r2,9)res=findCommon(r1,r2)# Print the array.print("[",end="")foriinrange(len(res)):print(res[i],end="")ifi!=len(res)-1:print(", ",end="")print("]")if__name__=="__main__":main()
C#
usingSystem;usingSystem.Collections.Generic;// Structure of a BST node.classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intval){data=val;left=right=null;}}classGFG{// Insert a node into the BST.staticNodeinsert(Noderoot,intkey){if(root==null)returnnewNode(key);if(key<root.data)root.left=insert(root.left,key);elseroot.right=insert(root.right,key);returnroot;}// Search for a key in the BST.staticboolsearch(Noderoot,intkey){if(root==null)returnfalse;if(root.data==key)returntrue;if(key<root.data)returnsearch(root.left,key);returnsearch(root.right,key);}// Traverse the first BST in inorder.staticvoidinorder(Noderoot,Noder2,List<int>res){if(root==null)return;inorder(root.left,r2,res);if(search(r2,root.data))res.Add(root.data);inorder(root.right,r2,res);}// Function to return the common nodes of two BSTs.staticList<int>findCommon(Noder1,Noder2){List<int>res=newList<int>();inorder(r1,r2,res);returnres;}staticvoidMain(){// First BST//// 5// / \// 1 10// / \ /// 0 4 7// \// 9//Noder1=null;r1=insert(r1,5);r1=insert(r1,1);r1=insert(r1,10);r1=insert(r1,0);r1=insert(r1,4);r1=insert(r1,7);r1=insert(r1,9);// Second BST//// 10// / \// 7 20// / \// 4 9//Noder2=null;r2=insert(r2,10);r2=insert(r2,7);r2=insert(r2,20);r2=insert(r2,4);r2=insert(r2,9);List<int>res=findCommon(r1,r2);// Print the array.Console.Write("[");for(inti=0;i<res.Count;i++){Console.Write(res[i]);if(i!=res.Count-1)Console.Write(", ");}Console.Write("]");}}
JavaScript
// Structure of a BST node.classNode{constructor(val){this.data=val;this.left=null;this.right=null;}}// Insert a node into the BST.functioninsert(root,key){if(!root)returnnewNode(key);if(key<root.data)root.left=insert(root.left,key);elseroot.right=insert(root.right,key);returnroot;}// Search for a key in the BST.functionsearch(root,key){if(!root)returnfalse;if(root.data===key)returntrue;if(key<root.data)returnsearch(root.left,key);returnsearch(root.right,key);}// Traverse the first BST in inorder.functioninorder(root,r2,res){if(!root)return;inorder(root.left,r2,res);if(search(r2,root.data))res.push(root.data);inorder(root.right,r2,res);}// Function to return the common nodes of two BSTs.functionfindCommon(r1,r2){letres=[];inorder(r1,r2,res);returnres;}// Driver code// First BST//// 5// / \// 1 10// / \ /// 0 4 7// \// 9//letr1=null;r1=insert(r1,5);r1=insert(r1,1);r1=insert(r1,10);r1=insert(r1,0);r1=insert(r1,4);r1=insert(r1,7);r1=insert(r1,9);// Second BST//// 10// / \// 7 20// / \// 4 9//letr2=null;r2=insert(r2,10);r2=insert(r2,7);r2=insert(r2,20);r2=insert(r2,4);r2=insert(r2,9);letres=findCommon(r1,r2);// Print the array.process.stdout.write("[");for(leti=0;i<res.length;i++){process.stdout.write(res[i].toString());if(i!==res.length-1)process.stdout.write(", ");}process.stdout.write("]");
Output
[4, 7, 9, 10]
[Expected Approach] Using Simultaneous Inorder Traversal - O(n + m) Time and O(h1 + h2) Space
The idea is to perform inorder traversal of both BSTs simultaneously using two stacks. The inorder traversal of a BST gives nodes in increasing order. Therefore, we can compare the current nodes of both BSTs similar to merging two sorted arrays.
Instead of storing complete inorder traversals, we store only the required nodes in stacks, which reduces extra space usage.
Use two stacks to perform simultaneous inorder traversal of both BSTs.
Push all left nodes of both BSTs into their respective stacks.
Compare the top nodes of both stacks:
If values are equal, add it to the result and move to their right subtrees.
If the first value is smaller, move ahead in the first BST.
Otherwise, move ahead in the second BST.
Repeat until either stack becomes empty.
Return the result array.
C++
#include<iostream>#include<vector>#include<stack>usingnamespacestd;// Structure of a BST node.classNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=right=nullptr;}};// Insert a node into the BST.Node*insert(Node*root,intkey){if(!root)returnnewNode(key);if(key<root->data)root->left=insert(root->left,key);elseroot->right=insert(root->right,key);returnroot;}// Function to return the common nodes of two BSTs.vector<int>findCommon(Node*r1,Node*r2){// Stacks for simultaneous inorder traversal of both BSTs.stack<Node*>s1,s2;vector<int>res;while(true){// Push all left nodes of first BST.while(r1){s1.push(r1);r1=r1->left;}// Push all left nodes of second BST.while(r2){s2.push(r2);r2=r2->left;}// Stop if either traversal is complete.if(s1.empty()||s2.empty())break;Node*curr1=s1.top();Node*curr2=s2.top();if(curr1->data==curr2->data){// Common node found.res.push_back(curr1->data);s1.pop();s2.pop();r1=curr1->right;r2=curr2->right;}elseif(curr1->data<curr2->data){// Advance in first BST.s1.pop();r1=curr1->right;r2=nullptr;}else{// Advance in second BST.s2.pop();r2=curr2->right;r1=nullptr;}}returnres;}intmain(){// First BST//// 5// / \ // 1 10// / \ /// 0 4 7// \ // 9//Node*r1=nullptr;r1=insert(r1,5);r1=insert(r1,1);r1=insert(r1,10);r1=insert(r1,0);r1=insert(r1,4);r1=insert(r1,7);r1=insert(r1,9);// Second BST//// 10// / \ // 7 20// / \ // 4 9//Node*r2=nullptr;r2=insert(r2,10);r2=insert(r2,7);r2=insert(r2,20);r2=insert(r2,4);r2=insert(r2,9);vector<int>res=findCommon(r1,r2);// Print the array.cout<<"[";for(inti=0;i<res.size();i++){cout<<res[i];if(i!=res.size()-1)cout<<", ";}cout<<"]";return0;}
Java
importjava.util.ArrayList;importjava.util.Stack;// Structure of a BST node.classNode{intdata;Nodeleft;Noderight;Node(intval){data=val;left=right=null;}}classGFG{// Insert a node into the BST.staticNodeinsert(Noderoot,intkey){if(root==null)returnnewNode(key);if(key<root.data)root.left=insert(root.left,key);elseroot.right=insert(root.right,key);returnroot;}// Function to return the common nodes of two BSTs.staticArrayList<Integer>findCommon(Noder1,Noder2){// Stacks for simultaneous inorder traversal of both BSTs.Stack<Node>s1=newStack<>();Stack<Node>s2=newStack<>();ArrayList<Integer>res=newArrayList<>();while(true){// Push all left nodes of first BST.while(r1!=null){s1.push(r1);r1=r1.left;}// Push all left nodes of second BST.while(r2!=null){s2.push(r2);r2=r2.left;}// Stop if either traversal is complete.if(s1.isEmpty()||s2.isEmpty())break;Nodecurr1=s1.peek();Nodecurr2=s2.peek();if(curr1.data==curr2.data){// Common node found.res.add(curr1.data);s1.pop();s2.pop();r1=curr1.right;r2=curr2.right;}elseif(curr1.data<curr2.data){// Advance in first BST.s1.pop();r1=curr1.right;r2=null;}else{// Advance in second BST.s2.pop();r2=curr2.right;r1=null;}}returnres;}publicstaticvoidmain(String[]args){// First BST//// 5// / \// 1 10// / \ /// 0 4 7// \// 9//Noder1=null;r1=insert(r1,5);r1=insert(r1,1);r1=insert(r1,10);r1=insert(r1,0);r1=insert(r1,4);r1=insert(r1,7);r1=insert(r1,9);// Second BST//// 10// / \// 7 20// / \// 4 9//Noder2=null;r2=insert(r2,10);r2=insert(r2,7);r2=insert(r2,20);r2=insert(r2,4);r2=insert(r2,9);ArrayList<Integer>res=findCommon(r1,r2);// Print the array.System.out.print("[");for(inti=0;i<res.size();i++){System.out.print(res.get(i));if(i!=res.size()-1)System.out.print(", ");}System.out.print("]");}}
Python
# Structure of a BST node.classNode:def__init__(self,val):self.data=valself.left=Noneself.right=None# Insert a node into the BST.definsert(root:'Node',key:int)->'Node':ifnotroot:returnNode(key)ifkey<root.data:root.left=insert(root.left,key)else:root.right=insert(root.right,key)returnroot# Function to return the common nodes of two BSTs.deffindCommon(r1:'Node',r2:'Node')->list[int]:# Stacks for simultaneous inorder traversal of both BSTs.s1=[]s2=[]res=[]whileTrue:# Push all left nodes of first BST.whiler1:s1.append(r1)r1=r1.left# Push all left nodes of second BST.whiler2:s2.append(r2)r2=r2.left# Stop if either traversal is complete.iflen(s1)==0orlen(s2)==0:breakcurr1=s1[-1]curr2=s2[-1]ifcurr1.data==curr2.data:# Common node found.res.append(curr1.data)s1.pop()s2.pop()r1=curr1.rightr2=curr2.rightelifcurr1.data<curr2.data:# Advance in first BST.s1.pop()r1=curr1.rightr2=Noneelse:# Advance in second BST.s2.pop()r2=curr2.rightr1=Nonereturnresif__name__=="__main__":# First BST## 5# / \# 1 10# / \ /# 0 4 7# \# 9#r1=Noner1=insert(r1,5)r1=insert(r1,1)r1=insert(r1,10)r1=insert(r1,0)r1=insert(r1,4)r1=insert(r1,7)r1=insert(r1,9)# Second BST## 10# / \# 7 20# / \# 4 9#r2=Noner2=insert(r2,10)r2=insert(r2,7)r2=insert(r2,20)r2=insert(r2,4)r2=insert(r2,9)res=findCommon(r1,r2)# Print the array.print("[",end="")foriinrange(len(res)):print(res[i],end="")ifi!=len(res)-1:print(", ",end="")print("]")
C#
usingSystem;usingSystem.Collections.Generic;// Structure of a BST node.classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intval){data=val;left=right=null;}}classGFG{// Insert a node into the BST.staticNodeinsert(Noderoot,intkey){if(root==null)returnnewNode(key);if(key<root.data)root.left=insert(root.left,key);elseroot.right=insert(root.right,key);returnroot;}// Function to return the common nodes of two BSTs.staticList<int>findCommon(Noder1,Noder2){// Stacks for simultaneous inorder traversal of both BSTs.Stack<Node>s1=newStack<Node>();Stack<Node>s2=newStack<Node>();List<int>res=newList<int>();while(true){// Push all left nodes of first BST.while(r1!=null){s1.Push(r1);r1=r1.left;}// Push all left nodes of second BST.while(r2!=null){s2.Push(r2);r2=r2.left;}// Stop if either traversal is complete.if(s1.Count==0||s2.Count==0)break;Nodecurr1=s1.Peek();Nodecurr2=s2.Peek();if(curr1.data==curr2.data){// Common node found.res.Add(curr1.data);s1.Pop();s2.Pop();r1=curr1.right;r2=curr2.right;}elseif(curr1.data<curr2.data){// Advance in first BST.s1.Pop();r1=curr1.right;r2=null;}else{// Advance in second BST.s2.Pop();r2=curr2.right;r1=null;}}returnres;}staticvoidMain(){// First BST//// 5// / \// 1 10// / \ /// 0 4 7// \// 9//Noder1=null;r1=insert(r1,5);r1=insert(r1,1);r1=insert(r1,10);r1=insert(r1,0);r1=insert(r1,4);r1=insert(r1,7);r1=insert(r1,9);// Second BST//// 10// / \// 7 20// / \// 4 9//Noder2=null;r2=insert(r2,10);r2=insert(r2,7);r2=insert(r2,20);r2=insert(r2,4);r2=insert(r2,9);List<int>res=findCommon(r1,r2);// Print the array.Console.Write("[");for(inti=0;i<res.Count;i++){Console.Write(res[i]);if(i!=res.Count-1)Console.Write(", ");}Console.Write("]");}}
JavaScript
// Structure of a BST node.classNode{constructor(val){this.data=val;this.left=null;this.right=null;}}// Insert a node into the BST.functioninsert(root,key){if(!root)returnnewNode(key);if(key<root.data)root.left=insert(root.left,key);elseroot.right=insert(root.right,key);returnroot;}// Function to return the common nodes of two BSTs.functionfindCommon(r1,r2){// Stacks for simultaneous inorder traversal of both BSTs.lets1=[];lets2=[];letres=[];while(true){// Push all left nodes of first BST.while(r1){s1.push(r1);r1=r1.left;}// Push all left nodes of second BST.while(r2){s2.push(r2);r2=r2.left;}// Stop if either traversal is complete.if(s1.length===0||s2.length===0)break;letcurr1=s1[s1.length-1];letcurr2=s2[s2.length-1];if(curr1.data===curr2.data){// Common node found.res.push(curr1.data);s1.pop();s2.pop();r1=curr1.right;r2=curr2.right;}elseif(curr1.data<curr2.data){// Advance in first BST.s1.pop();r1=curr1.right;r2=null;}else{// Advance in second BST.s2.pop();r2=curr2.right;r1=null;}}returnres;}// Driver code// First BST//// 5// / \// 1 10// / \ /// 0 4 7// \// 9//letr1=null;r1=insert(r1,5);r1=insert(r1,1);r1=insert(r1,10);r1=insert(r1,0);r1=insert(r1,4);r1=insert(r1,7);r1=insert(r1,9);// Second BST//// 10// / \// 7 20// / \// 4 9//letr2=null;r2=insert(r2,10);r2=insert(r2,7);r2=insert(r2,20);r2=insert(r2,4);r2=insert(r2,9);letres=findCommon(r1,r2);// Print the array.process.stdout.write("[");for(leti=0;i<res.length;i++){process.stdout.write(res[i].toString());if(i!==res.length-1)process.stdout.write(", ");}process.stdout.write("]");