Given the root of a Binary Search Tree (BST), where exactly two nodes have been swapped by mistake, restore the BST by swapping the values of the misplaced nodes. Return the root of the corrected BST.
Note: It is guaranteed that exactly two nodes have been swapped, and restoring their values will make the tree a valid BST. The structure of the tree must remain unchanged.
Examples:
Input: root = [6, 10, 2, 1, 3, 7, 12]
Output: [6, 2, 10, 1, 3, 7, 12] Explanation: After swapping the node 10 and 2. The tree satisfies the BST property.
Input: root = [1,2,3]
Output: [2,1, 3] Explanation: After swapping nodes 1 and 2, the tree becomes valid BST.
[Naive Approach] Using Inorder Traversal and Sorting - O(n * log n) Time and O(n) Space
The idea is to use the property of BST: an inorder traversal of a valid BST gives elements in sorted order. First, traverse the tree and store all node values in an array. Since exactly two nodes are swapped so that array will not be fully sorted. Sort the array to get the correct order of elements. Finally, traverse the tree again in inorder fashion, and replace each node’s value with the corresponding value from the sorted array. This restores the original BST structure while maintaining all other nodes in place.
C++
#include<iostream>#include<vector>#include<queue>#include<algorithm>usingnamespacestd;// Node structureclassNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=right=nullptr;}};// Print tree in level order array formatvoidprintTree(Node*root){if(root==nullptr){cout<<"[]\n";return;}vector<string>ans;queue<Node*>q;q.push(root);while(!q.empty()){Node*curr=q.front();q.pop();if(curr!=nullptr){ans.push_back(to_string(curr->data));q.push(curr->left);q.push(curr->right);}else{ans.push_back("N");}}while(!ans.empty()&&ans.back()=="N")ans.pop_back();cout<<"[";for(inti=0;i<ans.size();i++){if(i)cout<<", ";cout<<ans[i];}cout<<"]\n";}// Store inorder traversalvoidfindInorder(Node*root,vector<int>&inorder){if(root==nullptr)return;findInorder(root->left,inorder);inorder.push_back(root->data);findInorder(root->right,inorder);}// Replace node values using sorted inorder arrayvoidcorrectBSTUtil(Node*root,vector<int>&inorder,int&index){if(root==nullptr)return;correctBSTUtil(root->left,inorder,index);root->data=inorder[index++];correctBSTUtil(root->right,inorder,index);}// Function to restore the BSTNode*correctBST(Node*root){vector<int>inorder;findInorder(root,inorder);sort(inorder.begin(),inorder.end());intindex=0;correctBSTUtil(root,inorder,index);returnroot;}intmain(){// Constructing the tree with swapped nodes// 6// / \ // 10 2// / \ / \ // 1 3 7 12Node*root=newNode(6);root->left=newNode(10);root->right=newNode(2);root->left->left=newNode(1);root->left->right=newNode(3);root->right->left=newNode(7);root->right->right=newNode(12);root=correctBST(root);printTree(root);return0;}
Java
importjava.util.ArrayList;importjava.util.Queue;importjava.util.LinkedList;importjava.util.Collections;// Node structureclassNode{intdata;Nodeleft;Noderight;Node(intx){data=x;left=right=null;}}publicclassGFG{// Print tree in level order array formatstaticvoidprintTree(Noderoot){if(root==null){System.out.println("[]");return;}ArrayList<String>ans=newArrayList<>();Queue<Node>q=newLinkedList<>();q.offer(root);while(!q.isEmpty()){Nodecurr=q.poll();if(curr!=null){ans.add(String.valueOf(curr.data));q.offer(curr.left);q.offer(curr.right);}else{ans.add("N");}}while(!ans.isEmpty()&&ans.get(ans.size()-1).equals("N"))ans.remove(ans.size()-1);System.out.print("[");for(inti=0;i<ans.size();i++){if(i>0)System.out.print(", ");System.out.print(ans.get(i));}System.out.println("]");}// Store inorder traversalstaticvoidfindInorder(Noderoot,ArrayList<Integer>inorder){if(root==null)return;findInorder(root.left,inorder);inorder.add(root.data);findInorder(root.right,inorder);}// Replace node values using sorted inorder arraystaticvoidcorrectBSTUtil(Noderoot,ArrayList<Integer>inorder,int[]index){if(root==null)return;correctBSTUtil(root.left,inorder,index);root.data=inorder.get(index[0]++);correctBSTUtil(root.right,inorder,index);}// Function to restore the BSTstaticNodecorrectBST(Noderoot){ArrayList<Integer>inorder=newArrayList<>();findInorder(root,inorder);Collections.sort(inorder);int[]index={0};correctBSTUtil(root,inorder,index);returnroot;}publicstaticvoidmain(String[]args){// Constructing the tree with swapped nodes// 6// / \// 10 2// / \ / \// 1 3 7 12Noderoot=newNode(6);root.left=newNode(10);root.right=newNode(2);root.left.left=newNode(1);root.left.right=newNode(3);root.right.left=newNode(7);root.right.right=newNode(12);root=correctBST(root);printTree(root);}}
Python
fromcollectionsimportdeque# Node structureclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Print tree in level order array formatdefprintTree(root):ifrootisNone:print("[]")returnans=[]q=deque()q.append(root)whileq:curr=q.popleft()ifcurrisnotNone:ans.append(str(curr.data))q.append(curr.left)q.append(curr.right)else:ans.append("N")whileansandans[-1]=="N":ans.pop()print("["+", ".join(ans)+"]")# Store inorder traversaldeffindInorder(root,inorder):ifrootisNone:returnfindInorder(root.left,inorder)inorder.append(root.data)findInorder(root.right,inorder)# Replace node values using sorted inorder arraydefcorrectBSTUtil(root,inorder,index):ifrootisNone:returncorrectBSTUtil(root.left,inorder,index)root.data=inorder[index[0]]index[0]+=1correctBSTUtil(root.right,inorder,index)# Function to restore the BSTdefcorrectBST(root):inorder=[]findInorder(root,inorder)inorder.sort()index=[0]correctBSTUtil(root,inorder,index)returnrootif__name__=="__main__":# Constructing the tree with swapped nodes# 6# / \# 10 2# / \ / \# 1 3 7 12root=Node(6)root.left=Node(10)root.right=Node(2)root.left.left=Node(1)root.left.right=Node(3)root.right.left=Node(7)root.right.right=Node(12)root=correctBST(root)printTree(root)
C#
usingSystem;usingSystem.Collections.Generic;// Node structureclassNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intx){data=x;left=right=null;}}classGFG{// Print tree in level order array formatstaticvoidprintTree(Noderoot){if(root==null){Console.WriteLine("[]");return;}List<string>ans=newList<string>();Queue<Node>q=newQueue<Node>();q.Enqueue(root);while(q.Count>0){Nodecurr=q.Dequeue();if(curr!=null){ans.Add(curr.data.ToString());q.Enqueue(curr.left);q.Enqueue(curr.right);}else{ans.Add("N");}}while(ans.Count>0&&ans[ans.Count-1]=="N")ans.RemoveAt(ans.Count-1);Console.Write("[");for(inti=0;i<ans.Count;i++){if(i>0)Console.Write(", ");Console.Write(ans[i]);}Console.WriteLine("]");}// Store inorder traversalstaticvoidfindInorder(Noderoot,List<int>inorder){if(root==null)return;findInorder(root.left,inorder);inorder.Add(root.data);findInorder(root.right,inorder);}// Replace node values using sorted inorder arraystaticvoidcorrectBSTUtil(Noderoot,List<int>inorder,refintindex){if(root==null)return;correctBSTUtil(root.left,inorder,refindex);root.data=inorder[index++];correctBSTUtil(root.right,inorder,refindex);}// Function to restore the BSTstaticNodecorrectBST(Noderoot){List<int>inorder=newList<int>();findInorder(root,inorder);inorder.Sort();intindex=0;correctBSTUtil(root,inorder,refindex);returnroot;}staticvoidMain(){// Constructing the tree with swapped nodes// 6// / \// 10 2// / \ / \// 1 3 7 12Noderoot=newNode(6);root.left=newNode(10);root.right=newNode(2);root.left.left=newNode(1);root.left.right=newNode(3);root.right.left=newNode(7);root.right.right=newNode(12);root=correctBST(root);printTree(root);}}
JavaScript
// Node structureclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Print tree in level order array formatfunctionprintTree(root){if(root===null){console.log("[]");return;}letans=[];letq=[];q.push(root);while(q.length>0){letcurr=q.shift();if(curr!==null){ans.push(curr.data.toString());q.push(curr.left);q.push(curr.right);}else{ans.push("N");}}while(ans.length>0&&ans[ans.length-1]==="N")ans.pop();console.log("["+ans.join(", ")+"]");}// Store inorder traversalfunctionfindInorder(root,inorder){if(root===null)return;findInorder(root.left,inorder);inorder.push(root.data);findInorder(root.right,inorder);}// Replace node values using sorted inorder arrayfunctioncorrectBSTUtil(root,inorder,index){if(root===null)return;correctBSTUtil(root.left,inorder,index);root.data=inorder[index.value++];correctBSTUtil(root.right,inorder,index);}// Function to restore the BSTfunctioncorrectBST(root){letinorder=[];findInorder(root,inorder);inorder.sort((a,b)=>a-b);letindex={value:0};correctBSTUtil(root,inorder,index);returnroot;}// Driver code// Constructing the tree with swapped nodes// 6// / \// 10 2// / \ / \// 1 3 7 12letroot=newNode(6);root.left=newNode(10);root.right=newNode(2);root.left.left=newNode(1);root.left.right=newNode(3);root.right.left=newNode(7);root.right.right=newNode(12);root=correctBST(root);printTree(root);
Output
[6, 2, 10, 1, 3, 7, 12]
[Expected Approach] Using One Traversal - O(n) Time and O(h) Space
The inorder traversal of a BST always gives the node values in sorted order. If exactly two nodes are swapped, this sorted order is broken at one or two places.
During the inorder traversal, keep track of the previously visited node. Whenever the current node has a smaller value than the previous node, a BST violation is found.
For the first violation, store the previous node as first and the current node as middle.
If another violation is found, store the current node as last.
After the traversal:
If both first and last are found, swap their values as the swapped nodes are non-adjacent.
Otherwise, swap the values of first and middle, which handles the case when the swapped nodes are adjacent in the inorder traversal.
Consider the following tree where 10 and 2 are swapped:
The inorder traversal is: 1 10 3 6 7 2 12
Visit 1 -> No violation.
Visit 10 -> No violation (10 > 1).
Visit 3 -> 3 < 10, so the first violation is found , first = 10, middle = 3
Visit 6 and 7 -> No violation.
Visit 2 -> 2 < 7, so the second violation is found, last = 2
Visit 12 -> No violation.
After the traversal: first = 10, middle = 3, last = 2
Since both first and last are found, swap their value
The inorder traversal becomes: 1 2 3 6 7 10 12
The corrected BST is:
Hence, the BST is restored successfully.
C++
#include<iostream>#include<vector>#include<queue>#include<algorithm>usingnamespacestd;// Node structureclassNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=right=nullptr;}};// Print tree in level order array formatvoidprintTree(Node*root){if(root==nullptr){cout<<"[]\n";return;}vector<string>ans;queue<Node*>q;q.push(root);while(!q.empty()){Node*curr=q.front();q.pop();if(curr!=nullptr){ans.push_back(to_string(curr->data));q.push(curr->left);q.push(curr->right);}else{ans.push_back("N");}}while(!ans.empty()&&ans.back()=="N")ans.pop_back();cout<<"[";for(inti=0;i<ans.size();i++){if(i)cout<<", ";cout<<ans[i];}cout<<"]\n";}// Performs inorder traversal to find the misplaced nodes.voidcorrectBSTUtil(Node*root,Node*&first,Node*&middle,Node*&last,Node*&prev){if(root==nullptr)return;// Traverse left subtreecorrectBSTUtil(root->left,first,middle,last,prev);// Detect violation of BST propertyif(prev!=nullptr&&root->data<prev->data){// First violationif(first==nullptr){first=prev;middle=root;}// Second violationelse{last=root;}}prev=root;// Traverse right subtreecorrectBSTUtil(root->right,first,middle,last,prev);}Node*correctBST(Node*root){Node*first=nullptr,*middle=nullptr;Node*last=nullptr,*prev=nullptr;correctBSTUtil(root,first,middle,last,prev);// If the swapped nodes are non-adjacentif(first!=nullptr&&last!=nullptr)swap(first->data,last->data);// If the swapped nodes are adjacentelseif(first!=nullptr&&middle!=nullptr)swap(first->data,middle->data);returnroot;}intmain(){// Constructing the tree with swapped nodes// 6// / \ // 10 2// / \ / \ // 1 3 7 12Node*root=newNode(6);root->left=newNode(10);root->right=newNode(2);root->left->left=newNode(1);root->left->right=newNode(3);root->right->left=newNode(7);root->right->right=newNode(12);root=correctBST(root);printTree(root);return0;}
Java
importjava.util.ArrayList;importjava.util.Queue;importjava.util.LinkedList;// Node structureclassNode{intdata;Nodeleft;Noderight;Node(intx){data=x;left=right=null;}}classGFG{// Print tree in level order array formatstaticvoidprintTree(Noderoot){if(root==null){System.out.println("[]");return;}ArrayList<String>ans=newArrayList<>();Queue<Node>q=newLinkedList<>();q.offer(root);while(!q.isEmpty()){Nodecurr=q.poll();if(curr!=null){ans.add(String.valueOf(curr.data));q.offer(curr.left);q.offer(curr.right);}else{ans.add("N");}}while(!ans.isEmpty()&&ans.get(ans.size()-1).equals("N"))ans.remove(ans.size()-1);System.out.print("[");for(inti=0;i<ans.size();i++){if(i>0)System.out.print(", ");System.out.print(ans.get(i));}System.out.println("]");}// Performs inorder traversal to find the misplaced nodes.staticvoidcorrectBSTUtil(Noderoot,Node[]first,Node[]middle,Node[]last,Node[]prev){if(root==null)return;// Traverse left subtreecorrectBSTUtil(root.left,first,middle,last,prev);// Detect violation of BST propertyif(prev[0]!=null&&root.data<prev[0].data){// First violationif(first[0]==null){first[0]=prev[0];middle[0]=root;}// Second violationelse{last[0]=root;}}prev[0]=root;// Traverse right subtreecorrectBSTUtil(root.right,first,middle,last,prev);}staticNodecorrectBST(Noderoot){Node[]first=newNode[1];Node[]middle=newNode[1];Node[]last=newNode[1];Node[]prev=newNode[1];correctBSTUtil(root,first,middle,last,prev);// If the swapped nodes are non-adjacentif(first[0]!=null&&last[0]!=null){inttemp=first[0].data;first[0].data=last[0].data;last[0].data=temp;}// If the swapped nodes are adjacentelseif(first[0]!=null&&middle[0]!=null){inttemp=first[0].data;first[0].data=middle[0].data;middle[0].data=temp;}returnroot;}publicstaticvoidmain(String[]args){// Constructing the tree with swapped nodes// 6// / \// 10 2// / \ / \// 1 3 7 12Noderoot=newNode(6);root.left=newNode(10);root.right=newNode(2);root.left.left=newNode(1);root.left.right=newNode(3);root.right.left=newNode(7);root.right.right=newNode(12);root=correctBST(root);printTree(root);}}
Python
fromcollectionsimportdeque# Node structureclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Print tree in level order array formatdefprintTree(root):ifrootisNone:print("[]")returnans=[]q=deque()q.append(root)whileq:curr=q.popleft()ifcurrisnotNone:ans.append(str(curr.data))q.append(curr.left)q.append(curr.right)else:ans.append("N")whileansandans[-1]=="N":ans.pop()print("["+", ".join(ans)+"]")# Performs inorder traversal to find the misplaced nodes.defcorrectBSTUtil(root,first,middle,last,prev):ifrootisNone:return# Traverse left subtreecorrectBSTUtil(root.left,first,middle,last,prev)# Detect violation of BST propertyifprev[0]isnotNoneandroot.data<prev[0].data:# First violationiffirst[0]isNone:first[0]=prev[0]middle[0]=root# Second violationelse:last[0]=rootprev[0]=root# Traverse right subtreecorrectBSTUtil(root.right,first,middle,last,prev)defcorrectBST(root):first=[None]middle=[None]last=[None]prev=[None]correctBSTUtil(root,first,middle,last,prev)# If the swapped nodes are non-adjacentiffirst[0]isnotNoneandlast[0]isnotNone:first[0].data,last[0].data=last[0].data,first[0].data# If the swapped nodes are adjacenteliffirst[0]isnotNoneandmiddle[0]isnotNone:first[0].data,middle[0].data=middle[0].data,first[0].datareturnrootif__name__=="__main__":# Constructing the tree with swapped nodes# 6# / \# 10 2# / \ / \# 1 3 7 12root=Node(6)root.left=Node(10)root.right=Node(2)root.left.left=Node(1)root.left.right=Node(3)root.right.left=Node(7)root.right.right=Node(12)root=correctBST(root)printTree(root)
C#
usingSystem;usingSystem.Collections.Generic;// Node structureclassNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intx){data=x;left=right=null;}}classGFG{// Print tree in level order array formatstaticvoidprintTree(Noderoot){if(root==null){Console.WriteLine("[]");return;}List<string>ans=newList<string>();Queue<Node>q=newQueue<Node>();q.Enqueue(root);while(q.Count>0){Nodecurr=q.Dequeue();if(curr!=null){ans.Add(curr.data.ToString());q.Enqueue(curr.left);q.Enqueue(curr.right);}else{ans.Add("N");}}while(ans.Count>0&&ans[ans.Count-1]=="N")ans.RemoveAt(ans.Count-1);Console.Write("[");for(inti=0;i<ans.Count;i++){if(i>0)Console.Write(", ");Console.Write(ans[i]);}Console.WriteLine("]");}// Performs inorder traversal to find the misplaced nodes.staticvoidcorrectBSTUtil(Noderoot,refNodefirst,refNodemiddle,refNodelast,refNodeprev){if(root==null)return;// Traverse left subtreecorrectBSTUtil(root.left,reffirst,refmiddle,reflast,refprev);// Detect violation of BST propertyif(prev!=null&&root.data<prev.data){// First violationif(first==null){first=prev;middle=root;}// Second violationelse{last=root;}}prev=root;// Traverse right subtreecorrectBSTUtil(root.right,reffirst,refmiddle,reflast,refprev);}staticNodecorrectBST(Noderoot){Nodefirst=null;Nodemiddle=null;Nodelast=null;Nodeprev=null;correctBSTUtil(root,reffirst,refmiddle,reflast,refprev);// If the swapped nodes are non-adjacentif(first!=null&&last!=null){inttemp=first.data;first.data=last.data;last.data=temp;}// If the swapped nodes are adjacentelseif(first!=null&&middle!=null){inttemp=first.data;first.data=middle.data;middle.data=temp;}returnroot;}staticvoidMain(){// Constructing the tree with swapped nodes// 6// / \// 10 2// / \ / \// 1 3 7 12Noderoot=newNode(6);root.left=newNode(10);root.right=newNode(2);root.left.left=newNode(1);root.left.right=newNode(3);root.right.left=newNode(7);root.right.right=newNode(12);root=correctBST(root);printTree(root);}}
JavaScript
// Node structureclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Print tree in level order array formatfunctionprintTree(root){if(root===null){console.log("[]");return;}letans=[];letq=[];q.push(root);while(q.length>0){letcurr=q.shift();if(curr!==null){ans.push(curr.data.toString());q.push(curr.left);q.push(curr.right);}else{ans.push("N");}}while(ans.length>0&&ans[ans.length-1]==="N")ans.pop();console.log("["+ans.join(", ")+"]");}// Performs inorder traversal to find the misplaced nodes.functioncorrectBSTUtil(root,first,middle,last,prev){if(root===null)return;// Traverse left subtreecorrectBSTUtil(root.left,first,middle,last,prev);// Detect violation of BST propertyif(prev.node!==null&&root.data<prev.node.data){// First violationif(first.node===null){first.node=prev.node;middle.node=root;}// Second violationelse{last.node=root;}}prev.node=root;// Traverse right subtreecorrectBSTUtil(root.right,first,middle,last,prev);}functioncorrectBST(root){letfirst={node:null};letmiddle={node:null};letlast={node:null};letprev={node:null};correctBSTUtil(root,first,middle,last,prev);// If the swapped nodes are non-adjacentif(first.node!==null&&last.node!==null){lettemp=first.node.data;first.node.data=last.node.data;last.node.data=temp;}// If the swapped nodes are adjacentelseif(first.node!==null&&middle.node!==null){lettemp=first.node.data;first.node.data=middle.node.data;middle.node.data=temp;}returnroot;}// Driver code// Constructing the tree with swapped nodes// 6// / \// 10 2// / \ / \// 1 3 7 12letroot=newNode(6);root.left=newNode(10);root.right=newNode(2);root.left.left=newNode(1);root.left.right=newNode(3);root.right.left=newNode(7);root.right.right=newNode(12);root=correctBST(root);printTree(root);