Given a singly linked list whose elements are sorted in ascending order, construct a height-balanced Binary Search Tree (BST) containing the same elements as the linked list. A height-balanced BST is defined as a binary tree in which the depth difference between the left and right subtrees of every node is at most 1.
It is guaranteed that the linked list does not contain duplicate values.
The middle element would always be the root. In case of even elements, pick the root as second mid as root.
You need to return root of the tree, the preorder traversal is printed by the driver code to test your result.
Examples:
Input: Linked List : 1->2->3 Output: 2 1 3 Explanation: The BST formed using elements of the linked list is - Hence, the preorder traversal of this tree is 2 1 3.
Input: 1 2 3 4 5 6 7
Output: 4 2 1 3 6 5 7 Explanation: The BST formed using elements of the linked list is -
Hence, the preorder traversal of this tree is 4 2 1 3 6 5 7.
[Naive Approach] Using an Array - O(n) time and O(n) space
The core idea involves converting the linked list into an array. Then, the middle element of this array is used as the root, recursively building a balanced BST.
C++
#include<iostream>#include<vector>usingnamespacestd;classLNode{public:intdata;LNode*next;LNode(intx){data=x;next=nullptr;}};classTNode{public:intdata;TNode*left;TNode*right;TNode(intx){data=x;left=nullptr;right=nullptr;}};TNode*buildTree(vector<int>&arr,intstart,intend){if(start>end)returnnullptr;intmid=(start+end+1)/2;TNode*root=newTNode(arr[mid]);root->left=buildTree(arr,start,mid-1);root->right=buildTree(arr,mid+1,end);returnroot;}TNode*sortedListToBST(LNode*head){vector<int>arr;// Store elements of linked list into arraywhile(head){arr.push_back(head->data);head=head->next;}// Build BST from arrayreturnbuildTree(arr,0,arr.size()-1);}voidprintTree(TNode*root){if(!root)return;cout<<root->data<<" ";printTree(root->left);printTree(root->right);}intmain(){LNode*head=newLNode(1);head->next=newLNode(2);head->next->next=newLNode(3);head->next->next->next=newLNode(4);head->next->next->next->next=newLNode(5);head->next->next->next->next->next=newLNode(6);head->next->next->next->next->next->next=newLNode(7);TNode*root=sortedListToBST(head);printTree(root);return0;}
Java
importjava.util.ArrayList;classLNode{intdata;LNodenext;LNode(intx){data=x;next=null;}}classTNode{intdata;TNodeleft;TNoderight;TNode(intx){data=x;left=null;right=null;}}classGfG{staticTNodebuildTree(ArrayList<Integer>arr,intstart,intend){if(start>end)returnnull;intmid=(start+end+1)/2;TNoderoot=newTNode(arr.get(mid));root.left=buildTree(arr,start,mid-1);root.right=buildTree(arr,mid+1,end);returnroot;}staticTNodesortedListToBST(LNodehead){ArrayList<Integer>arr=newArrayList<>();// Store elements of linked list into arraywhile(head!=null){arr.add(head.data);head=head.next;}// Build BST from arrayreturnbuildTree(arr,0,arr.size()-1);}staticvoidprintTree(TNoderoot){if(root==null)return;System.out.print(root.data+" ");printTree(root.left);printTree(root.right);}publicstaticvoidmain(String[]args){LNodehead=newLNode(1);head.next=newLNode(2);head.next.next=newLNode(3);head.next.next.next=newLNode(4);head.next.next.next.next=newLNode(5);head.next.next.next.next.next=newLNode(6);head.next.next.next.next.next.next=newLNode(7);TNoderoot=sortedListToBST(head);printTree(root);}}
Python
classLNode:def__init__(self,x):self.data=xself.next=NoneclassTNode:def__init__(self,x):self.data=xself.left=Noneself.right=NonedefbuildTree(arr,start,end):ifstart>end:returnNonemid=(start+end+1)//2root=TNode(arr[mid])root.left=buildTree(arr,start,mid-1)root.right=buildTree(arr,mid+1,end)returnrootdefsortedListToBST(head):arr=[]# Store elements of linked list into arraywhilehead:arr.append(head.data)head=head.next# Build BST from arrayreturnbuildTree(arr,0,len(arr)-1)defprintTree(root):ifnotroot:returnprint(root.data,end=" ")printTree(root.left)printTree(root.right)if__name__=="__main__":head=LNode(1)head.next=LNode(2)head.next.next=LNode(3)head.next.next.next=LNode(4)head.next.next.next.next=LNode(5)head.next.next.next.next.next=LNode(6)head.next.next.next.next.next.next=LNode(7)root=sortedListToBST(head)printTree(root)
C#
usingSystem;usingSystem.Collections.Generic;classLNode{publicintdata;publicLNodenext;publicLNode(intx){data=x;next=null;}}classTNode{publicintdata;publicTNodeleft;publicTNoderight;publicTNode(intx){data=x;left=null;right=null;}}classGfG{staticTNodebuildTree(List<int>arr,intstart,intend){if(start>end)returnnull;intmid=(start+end+1)/2;TNoderoot=newTNode(arr[mid]);root.left=buildTree(arr,start,mid-1);root.right=buildTree(arr,mid+1,end);returnroot;}staticTNodesortedListToBST(LNodehead){List<int>arr=newList<int>();// Store elements of linked list into arraywhile(head!=null){arr.Add(head.data);head=head.next;}// Build BST from arrayreturnbuildTree(arr,0,arr.Count-1);}staticvoidprintTree(TNoderoot){if(root==null)return;Console.Write(root.data+" ");printTree(root.left);printTree(root.right);}publicstaticvoidMain(string[]args){LNodehead=newLNode(1);head.next=newLNode(2);head.next.next=newLNode(3);head.next.next.next=newLNode(4);head.next.next.next.next=newLNode(5);head.next.next.next.next.next=newLNode(6);head.next.next.next.next.next.next=newLNode(7);TNoderoot=sortedListToBST(head);printTree(root);}}
JavaScript
classLNode{constructor(x){this.data=x;this.next=null;}}classTNode{constructor(x){this.data=x;this.left=null;this.right=null;}}functionbuildTree(arr,start,end){if(start>end)returnnull;constmid=Math.floor((start+end+1)/2);constroot=newTNode(arr[mid]);root.left=buildTree(arr,start,mid-1);root.right=buildTree(arr,mid+1,end);returnroot;}functionsortedListToBST(head){constarr=[];// Store elements of linked list into arraywhile(head){arr.push(head.data);head=head.next;}// Build BST from arrayreturnbuildTree(arr,0,arr.length-1);}functionprintTree(root){if(!root)return;process.stdout.write(root.data+" ");printTree(root.left);printTree(root.right);}consthead=newLNode(1);head.next=newLNode(2);head.next.next=newLNode(3);head.next.next.next=newLNode(4);head.next.next.next.next=newLNode(5);head.next.next.next.next.next=newLNode(6);head.next.next.next.next.next.next=newLNode(7);constroot=sortedListToBST(head);printTree(root);
Output
4 2 1 3 6 5 7
[Expected Approach] In-Order Traversal - O(n) time and O(log n) space
This approach uses Inorder traversal to construct the tree directly from the linked list.
We first count nodes and use this count in the recursive calls to decide whether the current node would be root, go to left subtree or right subtree.
Let the count of nodes be n, we mainly pass n/2 to left subtree, build root and pass n - n/2 - 1 to right subtree.
C++
#include<iostream>usingnamespacestd;classLNode{public:intdata;LNode*next;LNode(intx){data=x;next=nullptr;}};classTNode{public:intdata;TNode*left;TNode*right;TNode(intx){data=x;left=nullptr;right=nullptr;}};intcountNodes(LNode*head){intcount=0;while(head){count++;head=head->next;}returncount;}TNode*buildTree(LNode*&headRef,intn){if(n<=0)returnnullptr;// Build left subtreeTNode*left=buildTree(headRef,n/2);// Create root nodeTNode*root=newTNode(headRef->data);root->left=left;// Move list head forwardheadRef=headRef->next;// Build right subtreeroot->right=buildTree(headRef,n-n/2-1);returnroot;}TNode*sortedListToBST(LNode*head){intn=countNodes(head);returnbuildTree(head,n);}voidprintTree(TNode*root){if(!root)return;cout<<root->data<<" ";printTree(root->left);printTree(root->right);}intmain(){LNode*head=newLNode(1);head->next=newLNode(2);head->next->next=newLNode(3);head->next->next->next=newLNode(4);head->next->next->next->next=newLNode(5);head->next->next->next->next->next=newLNode(6);head->next->next->next->next->next->next=newLNode(7);TNode*root=sortedListToBST(head);printTree(root);return0;}
Java
classLNode{intdata;LNodenext;LNode(intx){data=x;next=null;}}classTNode{intdata;TNodeleft;TNoderight;TNode(intx){data=x;left=null;right=null;}}classGfG{staticintcountNodes(LNodehead){intcount=0;while(head!=null){count++;head=head.next;}returncount;}staticTNodebuildTree(LNode[]headRef,intn){if(n<=0)returnnull;// Build left subtreeTNodeleft=buildTree(headRef,n/2);// Create root nodeTNoderoot=newTNode(headRef[0].data);root.left=left;// Move list head forwardheadRef[0]=headRef[0].next;// Build right subtreeroot.right=buildTree(headRef,n-n/2-1);returnroot;}staticTNodesortedListToBST(LNodehead){intn=countNodes(head);LNode[]headRef=newLNode[]{head};returnbuildTree(headRef,n);}staticvoidprintTree(TNoderoot){if(root==null)return;System.out.print(root.data+" ");printTree(root.left);printTree(root.right);}publicstaticvoidmain(String[]args){LNodehead=newLNode(1);head.next=newLNode(2);head.next.next=newLNode(3);head.next.next.next=newLNode(4);head.next.next.next.next=newLNode(5);head.next.next.next.next.next=newLNode(6);head.next.next.next.next.next.next=newLNode(7);TNoderoot=sortedListToBST(head);printTree(root);}}
Python
classLNode:def__init__(self,x):self.data=xself.next=NoneclassTNode:def__init__(self,x):self.data=xself.left=Noneself.right=NonedefcountNodes(head):count=0whilehead:count+=1head=head.nextreturncountdefbuildTree(headRef,n):ifn<=0:returnNone# Build left subtreeleft=buildTree(headRef,n//2)# Create root noderoot=TNode(headRef[0].data)root.left=left# Move list head forwardheadRef[0]=headRef[0].next# Build right subtreeroot.right=buildTree(headRef,n-n//2-1)returnrootdefsortedListToBST(head):n=countNodes(head)headRef=[head]returnbuildTree(headRef,n)defprintTree(root):ifnotroot:returnprint(root.data,end=" ")printTree(root.left)printTree(root.right)if__name__=="__main__":head=LNode(1)head.next=LNode(2)head.next.next=LNode(3)head.next.next.next=LNode(4)head.next.next.next.next=LNode(5)head.next.next.next.next.next=LNode(6)head.next.next.next.next.next.next=LNode(7)root=sortedListToBST(head)printTree(root)
C#
usingSystem;classLNode{publicintdata;publicLNodenext;publicLNode(intx){data=x;next=null;}}classTNode{publicintdata;publicTNodeleft;publicTNoderight;publicTNode(intx){data=x;left=null;right=null;}}classGfG{staticintcountNodes(LNodehead){intcount=0;while(head!=null){count++;head=head.next;}returncount;}staticTNodebuildTree(refLNodeheadRef,intn){if(n<=0)returnnull;// Build left subtreeTNodeleft=buildTree(refheadRef,n/2);// Create root nodeTNoderoot=newTNode(headRef.data);root.left=left;// Move list head forwardheadRef=headRef.next;// Build right subtreeroot.right=buildTree(refheadRef,n-n/2-1);returnroot;}staticTNodesortedListToBST(LNodehead){intn=countNodes(head);returnbuildTree(refhead,n);}staticvoidprintTree(TNoderoot){if(root==null)return;Console.Write(root.data+" ");printTree(root.left);printTree(root.right);}publicstaticvoidMain(string[]args){LNodehead=newLNode(1);head.next=newLNode(2);head.next.next=newLNode(3);head.next.next.next=newLNode(4);head.next.next.next.next=newLNode(5);head.next.next.next.next.next=newLNode(6);head.next.next.next.next.next.next=newLNode(7);TNoderoot=sortedListToBST(head);printTree(root);}}
JavaScript
classLNode{constructor(x){this.data=x;this.next=null;}}classTNode{constructor(x){this.data=x;this.left=null;this.right=null;}}functioncountNodes(head){letcount=0;while(head){count++;head=head.next;}returncount;}functionbuildTree(headRef,n){if(n<=0)returnnull;// Build left subtreeletleft=buildTree(headRef,Math.floor(n/2));// Create root nodeletroot=newTNode(headRef[0].data);root.left=left;// Move list head forwardheadRef[0]=headRef[0].next;// Build right subtreeroot.right=buildTree(headRef,n-Math.floor(n/2)-1);returnroot;}functionsortedListToBST(head){letn=countNodes(head);letheadRef=[head];returnbuildTree(headRef,n);}functionprintTree(root){if(!root)return;process.stdout.write(root.data+" ");printTree(root.left);printTree(root.right);}lethead=newLNode(1);head.next=newLNode(2);head.next.next=newLNode(3);head.next.next.next=newLNode(4);head.next.next.next.next=newLNode(5);head.next.next.next.next.next=newLNode(6);head.next.next.next.next.next.next=newLNode(7);letroot=sortedListToBST(head);printTree(root);