Given the root of a Binary Search Tree. Flatten the BST into a sorted linked list. Note: Flattening a BST means: Every node’s left child should be null and the right child points to the next node in sorted order. In other words, after flattening, the BST should behave like a singly linked list that follows the increasing order of node values.
Examples:
Input:
Output: [[2],[N, 3], [N, 4], [N, 5], [N, 6], [N, 7], [N, 8]] Explanation: After flattening, the BST becomes a right-skewed tree where all nodes follow the sorted order like a linked list.
Input:
Output: [[1]], [N, 2], [N, 3], [N, 4], [N, 5]] Explanation: After flattening, the BST becomes a right-skewed tree where all nodes follow the sorted order like a linked list.
[Naive Approach] By Storing Inorder Traversal - O(n) Time and O(n) Space
The approach is to traverse the BST in inorder to obtain the nodes in ascending order. Using this sequence, we rebuild the tree so that each node has no left child, and its right child points to the next node in the sorted list, resulting in a right-skewed tree.
C++
//Driver Code Starts#include<iostream>#include<vector>#include<queue>usingnamespacestd;// Node structurestructNode{intdata;Node*left;Node*right;Node(intdata){this->data=data;left=right=nullptr;}};// Calculate HeightintgetHeight(Node*root,inth){if(root==nullptr)returnh-1;returnmax(getHeight(root->left,h+1),getHeight(root->right,h+1));}// Print Level OrdervoidlevelOrder(Node*root){queue<pair<Node*,int>>q;q.push({root,0});intlastLevel=0;// function to get the height of treeintheight=getHeight(root,0);// printing the level order of treewhile(!q.empty()){autotop=q.front();q.pop();Node*node=top.first;intlvl=top.second;if(lvl>lastLevel){cout<<"";lastLevel=lvl;}// all levels are printedif(lvl>height)break;if(node->data!=-1)cout<<node->data<<" ";// printing null nodeelsecout<<"N ";// null node has no childrenif(node->data==-1)continue;if(node->left==nullptr)q.push({newNode(-1),lvl+1});elseq.push({node->left,lvl+1});if(node->right==nullptr)q.push({newNode(-1),lvl+1});elseq.push({node->right,lvl+1});}}//Driver Code Ends// Inorder traversal: store node values in a vectorvoidinorder(Node*root,vector<int>&values){if(!root)return;inorder(root->left,values);values.push_back(root->data);inorder(root->right,values);}// Build right-skewed tree from vectorNode*buildRightSkewedTree(constvector<int>&values){Node*dummy=newNode(-1);Node*prev=dummy;for(intval:values){prev->right=newNode(val);prev->left=nullptr;prev=prev->right;}Node*newRoot=dummy->right;deletedummy;returnnewRoot;}// Flatten BST Node*flattenBST(Node*root){vector<int>values;inorder(root,values);// Rebuild as right-skewed treereturnbuildRightSkewedTree(values);}//Driver Code Startsintmain(){// Build BST// 5 // / \ // 3 7 // / \ / \ // 2 4 6 8Node*root=newNode(5);root->left=newNode(3);root->right=newNode(7);root->left->left=newNode(2);root->left->right=newNode(4);root->right->left=newNode(6);root->right->right=newNode(8);Node*flatRoot=flattenBST(root);levelOrder(flatRoot);return0;}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.LinkedList;importjava.util.Queue;importjava.util.List;importjava.util.ArrayList;// Node structureclassNode{intdata;Nodeleft,right;Node(intdata){this.data=data;left=right=null;}}publicclassGFG{// Calculate HeightstaticintgetHeight(Noderoot,inth){if(root==null)returnh-1;returnMath.max(getHeight(root.left,h+1),getHeight(root.right,h+1));}// Print Level OrderstaticvoidlevelOrder(Noderoot){Queue<List<Object>>queue=newLinkedList<>();queue.offer(List.of(root,0));intlastLevel=0;// function to get the height of treeintheight=getHeight(root,0);// printing the level order of treewhile(!queue.isEmpty()){List<Object>top=queue.poll();Nodenode=(Node)top.get(0);intlvl=(int)top.get(1);if(lvl>lastLevel){System.out.println();lastLevel=lvl;}// all levels are printedif(lvl>height)break;// printing null nodeSystem.out.print((node.data==-1?"N":node.data)+" ");// null node has no childrenif(node.data==-1)continue;if(node.left==null)queue.offer(List.of(newNode(-1),lvl+1));elsequeue.offer(List.of(node.left,lvl+1));if(node.right==null)queue.offer(List.of(newNode(-1),lvl+1));elsequeue.offer(List.of(node.right,lvl+1));}}//Driver Code Ends// Inorder traversal: store node values in a liststaticvoidinorder(Noderoot,List<Integer>values){if(root==null)return;inorder(root.left,values);values.add(root.data);inorder(root.right,values);}// Build right-skewed tree from liststaticNodebuildRightSkewedTree(List<Integer>values){Nodedummy=newNode(-1);Nodeprev=dummy;for(intval:values){prev.right=newNode(val);prev.left=null;prev=prev.right;}returndummy.right;}// Flatten BST staticNodeflattenBST(Noderoot){List<Integer>values=newArrayList<>();inorder(root,values);// Rebuild as right-skewed treereturnbuildRightSkewedTree(values);}//Driver Code Startspublicstaticvoidmain(String[]args){// Build BST// 5 // / \ // 3 7 // / \ / \ // 2 4 6 8Noderoot=newNode(5);root.left=newNode(3);root.right=newNode(7);root.left.left=newNode(2);root.left.right=newNode(4);root.right.left=newNode(6);root.right.right=newNode(8);NodeflatRoot=flattenBST(root);levelOrder(flatRoot);}}//Driver Code Ends
Python
#Driver Code Startsfromcollectionsimportdeque# Node structureclassNode:def__init__(self,data):self.data=dataself.left=Noneself.right=None# Calculate HeightdefgetHeight(root,h):ifrootisNone:returnh-1returnmax(getHeight(root.left,h+1),getHeight(root.right,h+1))# Print level order traversaldeflevelOrder(root):queue=deque([[root,0]])lastLevel=0# function to get the height of treeheight=getHeight(root,0)# printing the level order of treewhilequeue:node,lvl=queue.popleft()iflvl>lastLevel:print()lastLevel=lvl# all levels are printediflvl>height:break# printing null nodeprint("N"ifnode.data==-1elsenode.data,end=" ")# null node has no childrenifnode.data==-1:continueifnode.leftisNone:queue.append([Node(-1),lvl+1])else:queue.append([node.left,lvl+1])ifnode.rightisNone:queue.append([Node(-1),lvl+1])else:queue.append([node.right,lvl+1])#Driver Code Ends# Inorder traversal: store node values in a listdefinorder(root,values):ifnotroot:returninorder(root.left,values)values.append(root.data)inorder(root.right,values)# Build right-skewed tree from listdefbuildRightSkewedTree(values):dummy=Node(-1)prev=dummyforvalinvalues:prev.right=Node(val)prev.left=Noneprev=prev.rightreturndummy.right# Flatten BST (naive approach)defflattenBST(root):values=[]inorder(root,values)# Rebuild as right-skewed treereturnbuildRightSkewedTree(values)#Driver Code Startsif__name__=="__main__":# Build BST# 5 # / \ # 3 7 # / \ / \ # 2 4 6 8root=Node(5)root.left=Node(3)root.right=Node(7)root.left.left=Node(2)root.left.right=Node(4)root.right.left=Node(6)root.right.right=Node(8)flatRoot=flattenBST(root)levelOrder(flatRoot)#Driver Code Ends
C#
//Driver Code StartsusingSystem;usingSystem.Collections.Generic;// Node structureclassNode{publicintdata;publicNodeleft,right;publicNode(intdata){this.data=data;left=right=null;}}classGFG{// Calculate HeightstaticintgetHeight(Noderoot,inth){if(root==null)returnh-1;returnMath.Max(getHeight(root.left,h+1),getHeight(root.right,h+1));}// Print level orderstaticvoidlevelOrder(Noderoot){Queue<(Node,int)>queue=newQueue<(Node,int)>();queue.Enqueue((root,0));intlastLevel=0;// function to get the height of treeintheight=getHeight(root,0);// printing the level order of treewhile(queue.Count>0){var(node,lvl)=queue.Dequeue();if(lvl>lastLevel){Console.WriteLine();lastLevel=lvl;}// all levels are printedif(lvl>height)break;// printing null nodeConsole.Write((node.data==-1?"N":node.data.ToString())+" ");// null node has no childrenif(node.data==-1)continue;if(node.left==null)queue.Enqueue((newNode(-1),lvl+1));elsequeue.Enqueue((node.left,lvl+1));if(node.right==null)queue.Enqueue((newNode(-1),lvl+1));elsequeue.Enqueue((node.right,lvl+1));}}//Driver Code Ends// Inorder traversal: store node values in a liststaticvoidinorder(Noderoot,List<int>values){if(root==null)return;inorder(root.left,values);values.Add(root.data);inorder(root.right,values);}// Build right-skewed tree from liststaticNodebuildRightSkewedTree(List<int>values){Nodedummy=newNode(-1);Nodeprev=dummy;foreach(intvalinvalues){prev.right=newNode(val);prev.left=null;prev=prev.right;}returndummy.right;}// Flatten BST staticNodeflattenBST(Noderoot){List<int>values=newList<int>();inorder(root,values);// Rebuild as right-skewed treereturnbuildRightSkewedTree(values);}//Driver Code StartsstaticvoidMain(string[]args){// Build BST// 5 // / \ // 3 7 // / \ / \ // 2 4 6 8Noderoot=newNode(5);root.left=newNode(3);root.right=newNode(7);root.left.left=newNode(2);root.left.right=newNode(4);root.right.left=newNode(6);root.right.right=newNode(8);NodeflatRoot=flattenBST(root);levelOrder(flatRoot);}}//Driver Code Ends
JavaScript
//Driver Code Starts// Node structureclassNode{constructor(data){this.data=data;this.left=null;this.right=null;}}classQNode{constructor(data){this.data=data;this.next=null;}}classQueue{constructor(){this.front=null;this.rear=null;}isEmpty(){returnthis.front===null;}enqueue(x){letnewNode=newQNode(x);if(this.rear===null){this.front=this.rear=newNode;return;}this.rear.next=newNode;this.rear=newNode;}dequeue(){if(this.front===null)returnnull;lettemp=this.front;this.front=this.front.next;if(this.front===null)this.rear=null;returntemp.data;}}// Calculate heightfunctiongetHeight(root,h){if(root===null)returnh-1;returnMath.max(getHeight(root.left,h+1),getHeight(root.right,h+1));}functionlevelOrder(root){letqueue=[];queue.push([root,0]);letlastLevel=0;// get the height of treeletheight=getHeight(root,0);// printing the level order of treewhile(queue.length>0){let[node,lvl]=queue.shift();if(lvl>lastLevel){console.log("");lastLevel=lvl;}// all levels are printedif(lvl>height)break;// printing null nodeprocess.stdout.write((node.data===-1?"N":node.data)+" ");// null node has no childrenif(node.data===-1)continue;if(node.left===null)queue.push([newNode(-1),lvl+1]);elsequeue.push([node.left,lvl+1]);if(node.right===null)queue.push([newNode(-1),lvl+1]);elsequeue.push([node.right,lvl+1]);}}//Driver Code Ends// Inorder traversal: store node values in a listfunctioninorder(root,values){if(!root)return;inorder(root.left,values);values.push(root.data);inorder(root.right,values);}// Build right-skewed tree from listfunctionbuildRightSkewedTree(values){constdummy=newNode(-1);letprev=dummy;for(letvalofvalues){prev.right=newNode(val);prev.left=null;prev=prev.right;}returndummy.right;}// Flatten BST functionflattenBST(root){constvalues=[];inorder(root,values);// Rebuild as right-skewed treereturnbuildRightSkewedTree(values);}//Driver Code Starts// Driver code// Build BST// 5 // / \ // 3 7 // / \ / \ // 2 4 6 8letroot=newNode(5);root.left=newNode(3);root.right=newNode(7);root.left.left=newNode(2);root.left.right=newNode(4);root.right.left=newNode(6);root.right.right=newNode(8);constflatRoot=flattenBST(root);levelOrder(flatRoot);//Driver Code Ends
Output
2
N 3
N 4
N 5
N 6
N 7
N 8
[Expected Approach] Using Single Traversal - O(n) Time and O(n) Space
The idea is to traverse the BST in inorder to maintain the sorted order. We maintain a dummy node with value -1 and a prev pointer initially pointing to this dummy node, representing the last processed node. For each node, we set its left child to null, link the previous node’s right child to the current node, and update prev to the current node, repeating this process for all nodes to create a right-skewed linked list in increasing order.
Pseudo- Code Idea:
if curr is equal to null return.
Recursive call for left subtree - flatten(curr -> left, prev).
set pre -> left = NULL, pre -> right = curr and pre = curr.
Recursive call for right subtree - flatten(curr -> right, prev).
C++
//Driver Code Starts#include<iostream>#include<queue>usingnamespacestd;// Node structurestructNode{intdata;Node*left;Node*right;Node(intdata){this->data=data;left=NULL;right=NULL;}};// Calculate HeightintgetHeight(Node*root,inth){if(root==nullptr)returnh-1;returnmax(getHeight(root->left,h+1),getHeight(root->right,h+1));}// Print Level OrdervoidlevelOrder(Node*root){queue<pair<Node*,int>>q;q.push({root,0});intlastLevel=0;// function to get the height of treeintheight=getHeight(root,0);// printing the level order of treewhile(!q.empty()){autotop=q.front();q.pop();Node*node=top.first;intlvl=top.second;if(lvl>lastLevel){cout<<"";lastLevel=lvl;}// all levels are printedif(lvl>height)break;if(node->data!=-1)cout<<node->data<<" ";// printing null nodeelsecout<<"N ";// null node has no childrenif(node->data==-1)continue;if(node->left==nullptr)q.push({newNode(-1),lvl+1});elseq.push({node->left,lvl+1});if(node->right==nullptr)q.push({newNode(-1),lvl+1});elseq.push({node->right,lvl+1});}}//Driver Code Ends// Function to perform in-order traversal// recursivelyvoidinorder(Node*curr,Node*&prev){// Base caseif(curr==NULL)return;inorder(curr->left,prev);prev->left=NULL;prev->right=curr;prev=curr;inorder(curr->right,prev);}// Function to flatten binary treeNode*flattenBST(Node*root){// Dummy nodeNode*dummy=newNode(-1);// Pointer to previous elementNode*prev=dummy;inorder(root,prev);prev->left=NULL;prev->right=NULL;Node*newRoot=dummy->right;deletedummy;returnnewRoot;}//Driver Code Startsintmain(){// Build BST// 5 // / \ // 3 7 // / \ / \ // 2 4 6 8Node*root=newNode(5);root->left=newNode(3);root->right=newNode(7);root->left->left=newNode(2);root->left->right=newNode(4);root->right->left=newNode(6);root->right->right=newNode(8);levelOrder(flattenBST(root));return0;}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.LinkedList;importjava.util.Queue;importjava.util.List;importjava.util.ArrayList;classGFG{// Node structurestaticclassNode{intdata;Nodeleft;Noderight;Node(intdata){this.data=data;left=null;right=null;}};// Calculate HeightstaticintgetHeight(Noderoot,inth){if(root==null)returnh-1;returnMath.max(getHeight(root.left,h+1),getHeight(root.right,h+1));}// Print level OrderstaticvoidlevelOrder(Noderoot){Queue<List<Object>>queue=newLinkedList<>();queue.offer(List.of(root,0));intlastLevel=0;// function to get the height of treeintheight=getHeight(root,0);// printing the level order of treewhile(!queue.isEmpty()){List<Object>top=queue.poll();Nodenode=(Node)top.get(0);intlvl=(int)top.get(1);if(lvl>lastLevel){System.out.println();lastLevel=lvl;}// all levels are printedif(lvl>height)break;// printing null nodeSystem.out.print((node.data==-1?"N":node.data)+" ");// null node has no childrenif(node.data==-1)continue;if(node.left==null)queue.offer(List.of(newNode(-1),lvl+1));elsequeue.offer(List.of(node.left,lvl+1));if(node.right==null)queue.offer(List.of(newNode(-1),lvl+1));elsequeue.offer(List.of(node.right,lvl+1));}}//Driver Code EndsstaticNodeprev;// Function to perform // in-order traversalstaticvoidInorder(Nodecurr){// Base caseif(curr==null)return;Inorder(curr.left);prev.left=null;prev.right=curr;prev=curr;Inorder(curr.right);}// Function to flatten binary tree staticNodeflattenBST(Noderoot){// Dummy nodeNodedummy=newNode(-1);// Pointer to previous// elementprev=dummy;Inorder(root);prev.left=null;prev.right=null;NodenewRoot=dummy.right;returnnewRoot;}//Driver Code Startspublicstaticvoidmain(String[]args){// Build BST// 5 // / \ // 3 7 // / \ / \ // 2 4 6 8Noderoot=newNode(5);root.left=newNode(3);root.right=newNode(7);root.left.left=newNode(2);root.left.right=newNode(4);root.right.left=newNode(6);root.right.right=newNode(8);levelOrder(flattenBST(root));}}//Driver Code Ends
Python
#Driver Code Startsfromcollectionsimportdeque# Node structureclassNode:def__init__(self,data):self.data=dataself.left=Noneself.right=None# Calculate HeightdefgetHeight(root,h):ifrootisNone:returnh-1returnmax(getHeight(root.left,h+1),getHeight(root.right,h+1))# Print Level OrderdeflevelOrder(root):queue=deque([[root,0]])lastLevel=0# function to get the height of treeheight=getHeight(root,0)# printing the level order of treewhilequeue:node,lvl=queue.popleft()iflvl>lastLevel:print()lastLevel=lvl# all levels are printediflvl>height:break# printing null nodeprint("N"ifnode.data==-1elsenode.data,end=" ")# null node has no childrenifnode.data==-1:continueifnode.leftisNone:queue.append([Node(-1),lvl+1])else:queue.append([node.left,lvl+1])ifnode.rightisNone:queue.append([Node(-1),lvl+1])else:queue.append([node.right,lvl+1])#Driver Code Endsglobalprev# Function to perform in-order traversal# recursivelydefinorder(curr):globalprev# Base caseif(curr==None):returninorder(curr.left)prev.left=Noneprev.right=currprev=currinorder(curr.right)# Function to flatten binary treedefflattenBST(root):globalprev# Dummy nodedummy=Node(-1)# Pointer to previous elementprev=dummyinorder(root)prev.left=Noneprev.right=NonenewRoot=dummy.rightreturnnewRoot#Driver Code Startsif__name__=='__main__':# Build BST# 5 # / \ # 3 7 # / \ / \ # 2 4 6 8root=Node(5)root.left=Node(3)root.right=Node(7)root.left.left=Node(2)root.left.right=Node(4)root.right.left=Node(6)root.right.right=Node(8)levelOrder(flattenBST(root))#Driver Code Ends
C#
//Driver Code StartsusingSystem;usingSystem.Collections.Generic;publicclassGFG{// Node structurepublicclassNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intdata){this.data=data;left=null;right=null;}};// Calculate HeightstaticintgetHeight(Noderoot,inth){if(root==null)returnh-1;returnMath.Max(getHeight(root.left,h+1),getHeight(root.right,h+1));}// Print Level OrderstaticvoidlevelOrder(Noderoot){Queue<(Node,int)>queue=newQueue<(Node,int)>();queue.Enqueue((root,0));intlastLevel=0;// function to get the height of treeintheight=getHeight(root,0);// printing the level order of treewhile(queue.Count>0){var(node,lvl)=queue.Dequeue();if(lvl>lastLevel){Console.WriteLine();lastLevel=lvl;}// all levels are printedif(lvl>height)break;// printing null nodeConsole.Write((node?.data==-1?"N":node?.data.ToString())+" ");// null node has no childrenif(node?.data==-1)continue;if(node.left==null)queue.Enqueue((newNode(-1),lvl+1));elsequeue.Enqueue((node.left,lvl+1));if(node.right==null)queue.Enqueue((newNode(-1),lvl+1));elsequeue.Enqueue((node.right,lvl+1));}}//Driver Code EndsstaticNodeprev;// Function to perform// in-order traversalstaticvoidInorder(Nodecurr){// Base caseif(curr==null)return;Inorder(curr.left);prev.left=null;prev.right=curr;prev=curr;Inorder(curr.right);}// Function to flatten binary treestaticNodeflattenBST(Nodeparent){// Dummy nodeNodedummy=newNode(-1);// Pointer to previous// elementprev=dummy;Inorder(parent);prev.left=null;prev.right=null;NodenewRoot=dummy.right;returnnewRoot;}//Driver Code StartspublicstaticvoidMain(string[]args){// Build BST// 5 // / \ // 3 7 // / \ / \ // 2 4 6 8Noderoot=newNode(5);root.left=newNode(3);root.right=newNode(7);root.left.left=newNode(2);root.left.right=newNode(4);root.right.left=newNode(6);root.right.right=newNode(8);levelOrder(flattenBST(root));}}//Driver Code Ends
JavaScript
//Driver Code Starts// Node structureclassNode{constructor(data){this.data=data;this.left=null;this.right=null;}}classQNode{constructor(data){this.data=data;this.next=null;}}classQueue{constructor(){this.front=null;this.rear=null;}isEmpty(){returnthis.front===null;}enqueue(x){letnewNode=newQNode(x);if(this.rear===null){this.front=this.rear=newNode;return;}this.rear.next=newNode;this.rear=newNode;}dequeue(){if(this.front===null)returnnull;lettemp=this.front;this.front=this.front.next;if(this.front===null)this.rear=null;returntemp.data;}}// Calculate HeightfunctiongetHeight(root,h){if(root===null)returnh-1;returnMath.max(getHeight(root.left,h+1),getHeight(root.right,h+1));}// Print level OrderfunctionlevelOrder(root){letqueue=[];queue.push([root,0]);letlastLevel=0;// get the height of treeletheight=getHeight(root,0);// printing the level order of treewhile(queue.length>0){let[node,lvl]=queue.shift();if(lvl>lastLevel){console.log("");lastLevel=lvl;}// all levels are printedif(lvl>height)break;// printing null nodeprocess.stdout.write((node.data===-1?"N":node.data)+" ");// null node has no childrenif(node.data===-1)continue;if(node.left===null)queue.push([newNode(-1),lvl+1]);elsequeue.push([node.left,lvl+1]);if(node.right===null)queue.push([newNode(-1),lvl+1]);elsequeue.push([node.right,lvl+1]);}}//Driver Code Ends// Function to perform in-order traversal recursivelyfunctioninorder(curr,prev){// Base caseif(curr===null)return;inorder(curr.left,prev);prev.node.right=curr;curr.left=null;prev.node=curr;inorder(curr.right,prev);}// Function to flatten binary treefunctionflattenBST(root){// Dummy nodeconstdummy=newNode(-1);// Pointer to previous elementconstprev={node:dummy};inorder(root,prev);prev.node.left=null;prev.node.right=null;constnewRoot=dummy.right;returnnewRoot;}//Driver Code Starts// Driver code// Build BST// 5 // / \ // 3 7 // / \ / \ // 2 4 6 8letroot=newNode(5);root.left=newNode(3);root.right=newNode(7);root.left.left=newNode(2);root.left.right=newNode(4);root.right.left=newNode(6);root.right.right=newNode(8);constflatRoot=flattenBST(root);levelOrder(flatRoot);//Driver Code Ends