Welcome to the daily solutions of our PROBLEM OF THE DAY (POTD). We will discuss the entire problem step-by-step and work towards developing an optimized solution. This will not only help you brush up on your concepts of Binary Search Trees but will also help you build up problem-solving skills.
POTD 15 October: Normal BST to Balanced BST
Given a Binary Search Tree, modify the given BST to be balanced and have the minimum possible height. Return the balanced BST.
Example 1:
Example 2:
How to Convert Normal BST to Balanced BST?
The idea is to do the Inorder traversal of the Binary Search Tree and store the nodes in an array. The array will be sorted since the given tree is a BST. Then the middle element of the sorted array will be root of the new BST, ensuring that the left and right subtrees have nearly equal heights. The left subtree and right subtree can then be formed recursively.
Step-by-step approach:
- Traverse the BST inorder and store each element into an array arr[] (The elements of inorder traversal would always be sorted).
- Now, use this arr[] to create a balanced binary tree. To do this, find the middle element of the arr[] and make it root node.
- All the elements on the left side of the middle element will be left subtree and all the elements on the right side of the middle element will be right subtree
- Now, recursively build our left subtrees by again taking the middle element from the left side array and making it root node of left subtree
- Similarly, build right subtree
Below is the implementation of above approach:
// C++ program to convert a left unbalanced BST to // a balanced BST class Solution
{ public :
// Function to store all nodes of the BST in a vector
void storeBSTNodes(Node* root, vector<Node*> &nodes)
{
// If root is NULL, return
if (root == NULL)
return ;
// Recursively store left subtree nodes
storeBSTNodes(root->left, nodes);
// Push current node to the vector
nodes.push_back(root);
// Recursively store right subtree nodes
storeBSTNodes(root->right, nodes);
}
// Function to build a balanced BST from a sorted vector of nodes
Node* buildTreeUtil(vector<Node*> &nodes, int start, int end)
{
// If start index is greater than end index, return NULL
if (start > end)
return NULL;
// Find the middle index
int mid = (start + end) / 2;
// Create a new root node with the middle node of the vector
Node *root = nodes[mid];
// Recursively build left subtree using nodes before mid
root->left = buildTreeUtil(nodes, start, mid - 1);
// Recursively build right subtree using nodes after mid
root->right = buildTreeUtil(nodes, mid + 1, end);
return root;
}
// Function to build a balanced BST from an unbalanced BST
Node* buildBalancedTree(Node* root)
{
// Create an empty vector to store nodes
vector<Node *> nodes;
// Store all nodes of the BST in the vector
storeBSTNodes(root, nodes);
// Get the size of the vector
int n = nodes.size();
// Build a balanced BST from the sorted vector of nodes
return buildTreeUtil(nodes, 0, n - 1);
}
}; |
// Java program to convert a left unbalanced BST to a // balanced BST class GfG
{ void storeBSTNodes(Node root, Vector<Node> nodes)
{
// Base case
if (root == null )
return ;
// Store nodes in Inorder (which is sorted
// order for BST)
storeBSTNodes(root.left, nodes);
nodes.add(root);
storeBSTNodes(root.right, nodes);
}
Node buildTreeUtil(Vector<Node> nodes, int start, int end)
{
// base case
if (start > end)
return null ;
/* Get the middle element and make it root */
int mid = (start + end) / 2 ;
Node node = nodes.get(mid);
/* Using index in Inorder traversal, construct
left and right subtress */
node.left = buildTreeUtil(nodes, start, mid - 1 );
node.right = buildTreeUtil(nodes, mid + 1 , end);
return node;
}
Node buildBalancedTree(Node root)
{
// Store nodes of given BST in sorted order
Vector<Node> nodes = new Vector<Node>();
storeBSTNodes(root, nodes);
// Constucts BST from nodes[]
int n = nodes.size();
return buildTreeUtil(nodes, 0 , n - 1 );
}
} |
# Python3 program to convert a left # unbalanced BST to a balanced BST import sys
sys.setrecursionlimit( 10 * * 6 )
class Solution:
def storeBSTNodes( self , root, nodes):
if root is None :
return
self .storeBSTNodes(root.left, nodes)
nodes.append(root)
self .storeBSTNodes(root.right, nodes)
def buildTreeUtil( self , nodes, start, end):
if start > end:
return None
mid = (start + end) / / 2
root = nodes[mid]
root.left = self .buildTreeUtil(nodes, start, mid - 1 )
root.right = self .buildTreeUtil(nodes, mid + 1 , end)
return root
def buildBalancedTree( self , root):
nodes = []
self .storeBSTNodes(root, nodes)
n = len (nodes)
return self .buildTreeUtil(nodes, 0 , n - 1 )
|
// JavaScript program to convert a left // unbalanced BST to a balanced BST class Solution { buildBalancedTree(root){
function storeBSTNodes(root, nodes) {
if (root == null ) return ;
storeBSTNodes(root.left, nodes);
nodes.push(root);
storeBSTNodes(root.right, nodes);
}
function buildTreeUtil(nodes, start, end) {
if (start > end) return null ;
let mid = Math.floor((start + end) / 2);
let root = nodes[mid];
root.left = buildTreeUtil(nodes, start, mid - 1);
root.right = buildTreeUtil(nodes, mid + 1, end);
return root;
}
let nodes = [];
storeBSTNodes(root, nodes);
let n = nodes.length;
return buildTreeUtil(nodes, 0, n - 1);
}
} |
Time Complexity: O(N), As we traverse every node in the BST twice, where N is the number of nodes.
Auxiliary Space: O(N), As we have used a array to store all the nodes of the BST.