Given the roots r1 and r2 of two Binary Search Trees (BSTs), merge the elements of both trees into a single sorted array and return it.
The returned array should contain all the elements from both BSTs, including duplicate values if they are present.
Examples:
Input:Â r1 = [3, 1, 5], r2 = [4, 2, 6]
Output: [1, 2, 3, 4, 5, 6] Explanation: The inorder traversals of the two BSTs are [1, 3, 5] and [2, 4, 6]. Merging these two sorted sequences gives [1, 2, 3, 4, 5, 6].
Output: [0, 1, 2, 3, 5, 8, 10]Â Explanation: The inorder traversals of the two BSTs are [1, 2, 8, 10] and [0, 3, 5]. Merging these two sorted sequences gives [0, 1, 2, 3, 5, 8, 10].
[Approach - 1] Using Array - O(n + m) Time and O(n + m) Space
The idea is to perform inorder traversal of both BSTs to get their elements in sorted order, store them in two arrays (or lists), and then merge these two sorted arrays using a two-pointer approach to produce a single sorted list containing all elements from both BSTs.
C++
#include<iostream>#include<vector>usingnamespacestd;// Node structureclassNode{public:intdata;Node*left,*right;Node(intx){data=x;left=nullptr;right=nullptr;}};// Function to perform inorder traversal of a BST// Stores elements in sorted order in the given vectorvoidinorder(Node*root,vector<int>&arr){if(!root)return;inorder(root->left,arr);arr.push_back(root->data);inorder(root->right,arr);}// Function to merge two sorted arrays into one sorted arrayvector<int>mergeArrays(vector<int>&arr1,vector<int>&arr2){vector<int>result;inti=0,j=0;// Traverse both arrays and pick the smaller elementwhile(i<arr1.size()&&j<arr2.size()){if(arr1[i]<=arr2[j]){result.push_back(arr1[i++]);}else{result.push_back(arr2[j++]);}}while(i<arr1.size())result.push_back(arr1[i++]);while(j<arr2.size())result.push_back(arr2[j++]);returnresult;}// Function to merge elements of two BSTs into a single sorted listvector<int>merge(Node*root1,Node*root2){vector<int>arr1,arr2;// Get inorder traversal of both BSTsinorder(root1,arr1);inorder(root2,arr2);returnmergeArrays(arr1,arr2);}intmain(){// Create binary tree 1// 3// / \ // 1 5Node*root1=newNode(3);root1->left=newNode(1);root1->right=newNode(5);// Create binary tree 2// 4// / \ // 2 6Node*root2=newNode(4);root2->left=newNode(2);root2->right=newNode(6);vector<int>res=merge(root1,root2);// 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;// Node structureclassNode{intdata;Nodeleft,right;Node(intx){data=x;left=null;right=null;}}classGFG{// Function to perform inorder traversal of a BST// Stores elements in sorted order in the given liststaticvoidinorder(Noderoot,ArrayList<Integer>arr){if(root==null)return;inorder(root.left,arr);arr.add(root.data);inorder(root.right,arr);}// Function to merge two sorted lists into one sorted liststaticArrayList<Integer>mergeArrays(ArrayList<Integer>arr1,ArrayList<Integer>arr2){ArrayList<Integer>result=newArrayList<>();inti=0,j=0;// Traverse both lists and pick the smaller elementwhile(i<arr1.size()&&j<arr2.size()){if(arr1.get(i)<=arr2.get(j)){result.add(arr1.get(i++));}else{result.add(arr2.get(j++));}}while(i<arr1.size())result.add(arr1.get(i++));while(j<arr2.size())result.add(arr2.get(j++));returnresult;}// Function to merge elements of two BSTs into a single sorted liststaticArrayList<Integer>merge(Noderoot1,Noderoot2){ArrayList<Integer>arr1=newArrayList<>();ArrayList<Integer>arr2=newArrayList<>();// Get inorder traversal of both BSTsinorder(root1,arr1);inorder(root2,arr2);returnmergeArrays(arr1,arr2);}publicstaticvoidmain(String[]args){// Create binary tree 1// 3// / \// 1 5Noderoot1=newNode(3);root1.left=newNode(1);root1.right=newNode(5);// Create binary tree 2// 4// / \// 2 6Noderoot2=newNode(4);root2.left=newNode(2);root2.right=newNode(6);ArrayList<Integer>res=merge(root1,root2);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
# Node structureclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Function to perform inorder traversal of a BST# Stores elements in sorted order in the given listdefinorder(root,arr):ifnotroot:returninorder(root.left,arr)arr.append(root.data)inorder(root.right,arr)# Function to merge two sorted lists into one sorted listdefmergeArrays(arr1,arr2):result=[]i=j=0# Traverse both lists and pick the smaller elementwhilei<len(arr1)andj<len(arr2):ifarr1[i]<=arr2[j]:result.append(arr1[i])i+=1else:result.append(arr2[j])j+=1whilei<len(arr1):result.append(arr1[i])i+=1whilej<len(arr2):result.append(arr2[j])j+=1returnresult# Function to merge elements of two BSTs into a single sorted listdefmerge(root1,root2):arr1,arr2=[],[]# Get inorder traversal of both BSTsinorder(root1,arr1)inorder(root2,arr2)returnmergeArrays(arr1,arr2)if__name__=="__main__":# Create binary tree 1# 3# / \# 1 5root1=Node(3)root1.left=Node(1)root1.right=Node(5)# Create binary tree 2# 4# / \# 2 6root2=Node(4)root2.left=Node(2)root2.right=Node(6)res=merge(root1,root2)# Print the array.print("[",end="")foriinrange(len(res)):print(res[i],end="")ifi!=len(res)-1:print(", ",end="")print("]")
C#
usingSystem;usingSystem.Collections.Generic;// Node structureclassNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=null;right=null;}}classGFG{// Function to perform inorder traversal of a BST// Stores elements in sorted order in the given liststaticvoidinorder(Noderoot,List<int>arr){if(root==null)return;inorder(root.left,arr);arr.Add(root.data);inorder(root.right,arr);}// Function to merge two sorted lists into one sorted liststaticList<int>mergeArrays(List<int>arr1,List<int>arr2){List<int>result=newList<int>();inti=0,j=0;// Traverse both lists and pick the smaller elementwhile(i<arr1.Count&&j<arr2.Count){if(arr1[i]<=arr2[j]){result.Add(arr1[i++]);}else{result.Add(arr2[j++]);}}while(i<arr1.Count)result.Add(arr1[i++]);while(j<arr2.Count)result.Add(arr2[j++]);returnresult;}// Function to merge elements of two BSTs into a single sorted liststaticList<int>merge(Noderoot1,Noderoot2){List<int>arr1=newList<int>();List<int>arr2=newList<int>();// Get inorder traversal of both BSTsinorder(root1,arr1);inorder(root2,arr2);returnmergeArrays(arr1,arr2);}staticvoidMain(){// Create binary tree 1// 3// / \// 1 5Noderoot1=newNode(3);root1.left=newNode(1);root1.right=newNode(5);// Create binary tree 2// 4// / \// 2 6Noderoot2=newNode(4);root2.left=newNode(2);root2.right=newNode(6);List<int>res=merge(root1,root2);// 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
// Node structureclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Function to perform inorder traversal of a BST// Stores elements in sorted order in the given arrayfunctioninorder(root,arr){if(!root)return;inorder(root.left,arr);arr.push(root.data);inorder(root.right,arr);}// Function to merge two sorted arrays into one sorted arrayfunctionmergeArrays(arr1,arr2){letresult=[];leti=0,j=0;// Traverse both arrays and pick the smaller elementwhile(i<arr1.length&&j<arr2.length){if(arr1[i]<=arr2[j]){result.push(arr1[i++]);}else{result.push(arr2[j++]);}}while(i<arr1.length)result.push(arr1[i++]);while(j<arr2.length)result.push(arr2[j++]);returnresult;}// Function to merge elements of two BSTs into a single sorted arrayfunctionmerge(root1,root2){letarr1=[],arr2=[];// Get inorder traversal of both BSTsinorder(root1,arr1);inorder(root2,arr2);returnmergeArrays(arr1,arr2);}// Driver Code// Create binary tree 1// 3// / \// 1 5letroot1=newNode(3);root1.left=newNode(1);root1.right=newNode(5);// Create binary tree 2// 4// / \// 2 6letroot2=newNode(4);root2.left=newNode(2);root2.right=newNode(6);letres=merge(root1,root2);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
[1, 2, 3, 4, 5, 6]
[Approach - 2] Using Stack - O(n + m) Time and O(n + m) Space
The idea is to perform the inorder traversal of both BSTs simultaneously using two stacks. Since the inorder traversal of a BST generates elements in sorted order, the top of each stack always represents the next smallest unprocessed element of that BST. By comparing these two elements, we can add the smaller one to the result and continue its traversal, thereby merging both BSTs directly into a sorted array.
Create two stacks to perform iterative inorder traversal of both BSTs.
Push all the left descendants of the current nodes onto their respective stacks.
Compare the top nodes of both stacks and remove the smaller one.
Add the removed node's value to the result and move to its right child.
Repeat the above steps until both stacks become empty.
Why using Stack?
Although recursion can perform the inorder traversal of a BST, it is not suitable here because we need to traverse both BSTs simultaneously and compare their next inorder elements at each step. Using two stacks allows us to pause and resume the traversal of either tree whenever required, making it possible to merge the elements directly into a sorted array without storing the complete inorder traversals.
C++
#include<iostream>#include<vector>#include<stack>usingnamespacestd;// Node structureclassNode{public:intdata;Node*left,*right;Node(intx){data=x;left=nullptr;right=nullptr;}};vector<int>merge(Node*root1,Node*root2){vector<int>res;stack<Node*>s1,s2;while(root1||root2||!s1.empty()||!s2.empty()){// move to the leftmost nodes(min values)while(root1){s1.push(root1);root1=root1->left;}while(root2){s2.push(root2);root2=root2->left;}// compare the top element and remove // it and move to its right childif(s2.empty()||(!s1.empty()&&s1.top()->data<=s2.top()->data)){root1=s1.top();s1.pop();res.push_back(root1->data);root1=root1->right;}else{root2=s2.top();s2.pop();res.push_back(root2->data);root2=root2->right;}}returnres;}intmain(){// Create binary tree 1// 3// / \ // 1 5Node*root1=newNode(3);root1->left=newNode(1);root1->right=newNode(5);// Create binary tree 2// 4// / \ // 2 6Node*root2=newNode(4);root2->left=newNode(2);root2->right=newNode(6);vector<int>res=merge(root1,root2);// 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;// Node structureclassNode{intdata;Nodeleft,right;Node(intx){data=x;left=null;right=null;}}classGFG{staticArrayList<Integer>merge(Noderoot1,Noderoot2){ArrayList<Integer>res=newArrayList<>();Stack<Node>s1=newStack<>();Stack<Node>s2=newStack<>();while(root1!=null||root2!=null||!s1.empty()||!s2.empty()){// move to the leftmost nodes(min values)while(root1!=null){s1.push(root1);root1=root1.left;}while(root2!=null){s2.push(root2);root2=root2.left;}// compare the top element and remove // it and move to its right childif(s2.empty()||(!s1.empty()&&s1.peek().data<=s2.peek().data)){root1=s1.pop();res.add(root1.data);root1=root1.right;}else{root2=s2.pop();res.add(root2.data);root2=root2.right;}}returnres;}publicstaticvoidmain(String[]args){// Create binary tree 1// 3// / \// 1 5Noderoot1=newNode(3);root1.left=newNode(1);root1.right=newNode(5);// Create binary tree 2// 4// / \// 2 6Noderoot2=newNode(4);root2.left=newNode(2);root2.right=newNode(6);ArrayList<Integer>res=merge(root1,root2);// 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
# Node structureclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=Nonedefmerge(root1,root2):res=[]s1=[]s2=[]whileroot1orroot2ors1ors2:whileroot1:# move to the leftmost nodes(min values)s1.append(root1)root1=root1.leftwhileroot2:s2.append(root2)root2=root2.left# compare the top element and remove # it and move to its right childifnots2or(s1ands1[-1].data<=s2[-1].data):root1=s1.pop()res.append(root1.data)root1=root1.rightelse:root2=s2.pop()res.append(root2.data)root2=root2.rightreturnresif__name__=="__main__":# Create binary tree 1# 3# / \# 1 5root1=Node(3)root1.left=Node(1)root1.right=Node(5)# Create binary tree 2# 4# / \# 2 6root2=Node(4)root2.left=Node(2)root2.right=Node(6)res=merge(root1,root2)# Print the array.print("[",end="")foriinrange(len(res)):print(res[i],end="")ifi!=len(res)-1:print(", ",end="")print("]")
C#
usingSystem;usingSystem.Collections.Generic;// Node structureclassNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=null;right=null;}}classGFG{staticList<int>merge(Noderoot1,Noderoot2){List<int>res=newList<int>();Stack<Node>s1=newStack<Node>();Stack<Node>s2=newStack<Node>();while(root1!=null||root2!=null||s1.Count>0||s2.Count>0){// move to the leftmost nodes(min values)while(root1!=null){s1.Push(root1);root1=root1.left;}while(root2!=null){s2.Push(root2);root2=root2.left;}// compare the top element and remove // it and move to its right childif(s2.Count==0||(s1.Count>0&&s1.Peek().data<=s2.Peek().data)){root1=s1.Pop();res.Add(root1.data);root1=root1.right;}else{root2=s2.Pop();res.Add(root2.data);root2=root2.right;}}returnres;}staticvoidMain(){// Create binary tree 1// 3// / \// 1 5Noderoot1=newNode(3);root1.left=newNode(1);root1.right=newNode(5);// Create binary tree 2// 4// / \// 2 6Noderoot2=newNode(4);root2.left=newNode(2);root2.right=newNode(6);List<int>res=merge(root1,root2);// 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
// Node structureclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}functionmerge(root1,root2){letres=[];lets1=[];lets2=[];while(root1||root2||s1.length>0||s2.length>0){while(root1){// move to the leftmost nodes(min values)s1.push(root1);root1=root1.left;}while(root2){s2.push(root2);root2=root2.left;}// compare the top element and remove // it and move to its right childif(s2.length===0||(s1.length>0&&s1[s1.length-1].data<=s2[s2.length-1].data)){root1=s1.pop();res.push(root1.data);root1=root1.right;}else{root2=s2.pop();res.push(root2.data);root2=root2.right;}}returnres;}// Create binary tree 1// 3// / \// 1 5letroot1=newNode(3);root1.left=newNode(1);root1.right=newNode(5);// Create binary tree 2// 4// / \// 2 6letroot2=newNode(4);root2.left=newNode(2);root2.right=newNode(6);letres=merge(root1,root2);// 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("]");