Given a Binary Tree, the task is to return the size of the largest subtree which is also a Binary Search Tree (BST). If the complete Binary Tree is BST, then return the size of the whole tree.
Examples:
Input:
Output: 3 Explanation: The below subtree is the maximum size BST:
Input:
Output: 3 Explanation: The below subtree is the maximum size BST:
Prerequisite : Validate BST (Minimum and Maximum Value Approach)
[Naive Approach] Using Recursion - O(n^2) Time and O(n) Space
The idea is simple, we traverse through the Binary tree (starting from root). For every node, we check if it is BST. If yes, then we return size of the subtree rooted with current node. Else, we recursively call for left and right subtrees and return the maximum of two calls.
Below is the implementation of the above approach.
C++
// C++ Program to find Size of Largest BST// in a Binary Tree#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=nullptr;right=nullptr;}};// Returns true if the given tree is BST, else falseboolisValidBst(Node*root,intminValue,intmaxValue){if(!root)returntrue;if(root->data>=maxValue||root->data<=minValue)returnfalse;returnisValidBst(root->left,minValue,root->data)&&isValidBst(root->right,root->data,maxValue);}// Returns size of a treeintsize(Node*root){if(!root)return0;return1+size(root->left)+size(root->right);}// Finds the size of the largest BSTintlargestBst(Node*root){// If tree is emptyif(!root)return0;// If whole tree is BSTif(isValidBst(root,INT_MIN,INT_MAX))returnsize(root);// If whole tree is not BSTreturnmax(largestBst(root->left),largestBst(root->right));}intmain(){// Constructed binary tree looks like this:// 50// / \ // 75 45// /// 40Node*root=newNode(50);root->left=newNode(75);root->right=newNode(45);root->left->left=newNode(40);cout<<largestBst(root)<<endl;return0;}
C
// C Program to find Size of Largest// BST in a Binary Tree#include<stdio.h>#include<stdlib.h>#include<limits.h>structNode{intdata;structNode*left,*right;};// Returns true if the given tree is BST, else falseintisValidBst(structNode*root,intminValue,intmaxValue){if(!root)return1;if(root->data>=maxValue||root->data<=minValue)return0;returnisValidBst(root->left,minValue,root->data)&&isValidBst(root->right,root->data,maxValue);}// Returns size of a treeintsize(structNode*root){if(!root)return0;return1+size(root->left)+size(root->right);}// Finds the size of the largest BSTintlargestBst(structNode*root){// If tree is emptyif(!root)return0;// If whole tree is BSTif(isValidBst(root,INT_MIN,INT_MAX))returnsize(root);// If whole tree is not BSTreturn(largestBst(root->left)>largestBst(root->right))?largestBst(root->left):largestBst(root->right);}structNode*createNode(intvalue){structNode*node=(structNode*)malloc(sizeof(structNode));node->data=value;node->left=node->right=NULL;returnnode;}intmain(){// Constructed binary tree looks like this:// 50// / \ // 75 45// /// 40structNode*root=createNode(50);root->left=createNode(75);root->right=createNode(45);root->left->left=createNode(40);printf("%d\n",largestBst(root));return0;}
Java
// Java Program to find Size of Largest // BST in a Binary TreeclassNode{intdata;Nodeleft,right;Node(intx){data=x;left=null;right=null;}}classGfG{// Returns true if the given tree is// BST, else falsestaticbooleanisValidBst(Noderoot,intminValue,intmaxValue){if(root==null){returntrue;}if(root.data>=maxValue||root.data<=minValue){returnfalse;}returnisValidBst(root.left,minValue,root.data)&&isValidBst(root.right,root.data,maxValue);}// Returns size of a treestaticintsize(Noderoot){if(root==null){return0;}return1+size(root.left)+size(root.right);}// Finds the size of the largest BSTstaticintlargestBst(Noderoot){// If tree is emptyif(root==null){return0;}// If whole tree is BSTif(isValidBst(root,Integer.MIN_VALUE,Integer.MAX_VALUE)){returnsize(root);}// If whole tree is not BSTreturnMath.max(largestBst(root.left),largestBst(root.right));}publicstaticvoidmain(String[]args){// Constructed binary tree looks like this:// 50// / \// 75 45// /// 40Noderoot=newNode(50);root.left=newNode(75);root.right=newNode(45);root.left.left=newNode(40);System.out.println(largestBst(root));}}
Python
# Python Program to find Size of Largest # BST in a Binary TreeclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Returns true if the given tree is BST, else falsedefisValidBst(root,minValue,maxValue):ifnotroot:returnTrueifroot.data>=maxValueorroot.data<=minValue:returnFalsereturn(isValidBst(root.left,minValue,root.data)andisValidBst(root.right,root.data,maxValue))# Returns size of a treedefsize(root):ifnotroot:return0return1+size(root.left)+size(root.right)# Finds the size of the largest BSTdeflargestBst(root):# If tree is emptyifnotroot:return0# If whole tree is BSTifisValidBst(root,float('-inf'),float('inf')):returnsize(root)# If whole tree is not BSTreturnmax(largestBst(root.left),largestBst(root.right))if__name__=="__main__":# Constructed binary tree looks like this:# 50# / \# 75 45# /# 40root=Node(50)root.left=Node(75)root.right=Node(45)root.left.left=Node(40)print(largestBst(root))
C#
// C# Program to find Size of Largest // BST in a Binary TreeusingSystem;classNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=null;right=null;}}classGfG{// Returns true if the given tree is BST, else falsestaticboolIsValidBst(Noderoot,intminValue,intmaxValue){if(root==null){returntrue;}if(root.data>=maxValue||root.data<=minValue){returnfalse;}returnIsValidBst(root.left,minValue,root.data)&&IsValidBst(root.right,root.data,maxValue);}// Returns size of a treestaticintSize(Noderoot){if(root==null){return0;}return1+Size(root.left)+Size(root.right);}// Finds the size of the largest BSTstaticintLargestBst(Noderoot){// If tree is emptyif(root==null){return0;}// If whole tree is BSTif(IsValidBst(root,int.MinValue,int.MaxValue)){returnSize(root);}// If whole tree is not BSTreturnMath.Max(LargestBst(root.left),LargestBst(root.right));}staticvoidMain(string[]args){// Constructed binary tree looks like this:// 50// / \// 75 45// /// 40Noderoot=newNode(50);root.left=newNode(75);root.right=newNode(45);root.left.left=newNode(40);Console.WriteLine(LargestBst(root));}}
JavaScript
// JavaScript Program to find Size of // Largest BST in a Binary TreeclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Returns true if the given tree is BST, else falsefunctionisValidBst(root,minValue,maxValue){if(!root)returntrue;if(root.data>=maxValue||root.data<=minValue)returnfalse;returnisValidBst(root.left,minValue,root.data)&&isValidBst(root.right,root.data,maxValue);}// Returns size of a treefunctionsize(root){if(!root)return0;return1+size(root.left)+size(root.right);}// Finds the size of the largest BSTfunctionlargestBst(root){// If tree is emptyif(!root)return0;// If whole tree is BSTif(isValidBst(root,-Infinity,Infinity))returnsize(root);// If whole tree is not BSTreturnMath.max(largestBst(root.left),largestBst(root.right));}// Constructed binary tree looks like this:// 50// / \// 75 45// /// 40letroot=newNode(50);root.left=newNode(75);root.right=newNode(45);root.left.left=newNode(40);console.log(largestBst(root));
Output
2
[Expected Approach] - Using Binary Search Tree Property - O(n) Time and O(n) Space
The largest value in left subtree (of x) is smaller than value of x.
The smallest value in right subtree (of x) is greater than value of x.
We traverse the tree in a bottom-up manner. For every traversed node, we return the maximum and minimum values in the subtree rooted at that node. The idea is to determine whether the subtree rooted at each node is a Binary Search Tree (BST). If any node follows the properties of a BST and has the maximum size, we update the size of the largest BST.
Step-By-Step Implementation :
Create a structure to store the minimum value, maximum value, and size of the largest BST for any given subtree.
Implement a recursive function that traverse through the binary tree. For each node, first, recursively gather information from its left and right children.
For each node, check whether the current subtree is a BST by comparing the node's value with the maximum of the left subtree and the minimum of the right subtree. If the conditions are satisfied, update the size of the largest BST found by combining the sizes of the valid left and right subtrees with the current node.
As the recursive calls return, keep track of the largest BST size. Finally, after traversing the entire tree, return the size of the largest BST found.
Below is the implementation of the above approach.
C++
// C++ Program to find Size of Largest BST in a Binary Tree#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=nullptr;right=nullptr;}};// Information about the subtree: Minimum value,// Maximum value, and Size of the largest BSTclassBSTInfo{public:intmin;intmax;intmxSz;BSTInfo(intmn,intmx,intsz){min=mn;max=mx;mxSz=sz;}};// Function to determine the largest BST in the binary treeBSTInfolargestBSTBT(Node*root){if(!root)returnBSTInfo(INT_MAX,INT_MIN,0);BSTInfoleft=largestBSTBT(root->left);BSTInforight=largestBSTBT(root->right);// Check if the current subtree is a BSTif(left.max<root->data&&right.min>root->data){returnBSTInfo(min(left.min,root->data),max(right.max,root->data),1+left.mxSz+right.mxSz);}returnBSTInfo(INT_MIN,INT_MAX,max(left.mxSz,right.mxSz));}// Function to return the size of the largest BSTintlargestBST(Node*root){returnlargestBSTBT(root).mxSz;}intmain(){// Constructed binary tree looks like this:// 60// / \ // 65 70// /// 50Node*root=newNode(60);root->left=newNode(65);root->right=newNode(70);root->left->left=newNode(50);cout<<largestBST(root)<<endl;return0;}
Java
// Java Program to find Size of Largest BST in a Binary TreeclassNode{intdata;Nodeleft,right;Node(intval){data=val;left=null;right=null;}}// Information about the subtree: Minimum value,// Maximum value, and Size of the largest BSTclassBSTInfo{intmin;intmax;intmxSz;BSTInfo(intmn,intmx,intsz){min=mn;max=mx;mxSz=sz;}}classGfG{// Function to determine the largest BST in the binary// treestaticBSTInfolargestBstBt(Noderoot){if(root==null)returnnewBSTInfo(Integer.MAX_VALUE,Integer.MIN_VALUE,0);BSTInfoleft=largestBstBt(root.left);BSTInforight=largestBstBt(root.right);// Check if the current subtree is a BSTif(left.max<root.data&&right.min>root.data){returnnewBSTInfo(Math.min(left.min,root.data),Math.max(right.max,root.data),1+left.mxSz+right.mxSz);}returnnewBSTInfo(Integer.MIN_VALUE,Integer.MAX_VALUE,Math.max(left.mxSz,right.mxSz));}// Function to return the size of the largest BSTstaticintlargestBst(Noderoot){returnlargestBstBt(root).mxSz;}publicstaticvoidmain(String[]args){// Constructed binary tree looks like this:// 60// / \// 65 70// /// 50Noderoot=newNode(60);root.left=newNode(65);root.right=newNode(70);root.left.left=newNode(50);System.out.println(largestBst(root));}}
Python
importsysclassNode:def__init__(self,data):self.data=dataself.left=Noneself.right=None# BSTInfo structure to store subtree informationclassBSTInfo:def__init__(self,min_val,max_val,max_size):self.min=min_valself.max=max_valself.maxSize=max_size# Function to determine the largest BST in the binary treedeflargestBSTBT(root):ifnotroot:returnBSTInfo(sys.maxsize,-sys.maxsize-1,0)left=largestBSTBT(root.left)right=largestBSTBT(root.right)# Check if the current subtree is a BSTifleft.max<root.data<right.min:returnBSTInfo(min(left.min,root.data),max(right.max,root.data),1+left.maxSize+right.maxSize)returnBSTInfo(-sys.maxsize-1,sys.maxsize,max(left.maxSize,right.maxSize))# Function to return the size of the largest BSTdeflargestBST(root):returnlargestBSTBT(root).maxSizeif__name__=="__main__":# Constructed binary tree looks like this:# 60# / \# 65 70# /# 50root=Node(60)root.left=Node(65)root.right=Node(70)root.left.left=Node(50)print(largestBST(root))
C#
// C# Program to find Size of Largest BST// in a Binary TreeusingSystem;classNode{publicintdata;publicNodeleft,right;publicNode(intval){data=val;left=null;right=null;}}// Information about the subtree: Minimum value,// Maximum value, and Size of the largest BSTclassBSTInfo{publicintmin;publicintmax;publicintmxSz;publicBSTInfo(intmn,intmx,intsz){min=mn;max=mx;mxSz=sz;}}classGfG{// Function to determine the largest BST in the binary// treestaticBSTInfoLargestBstBt(Noderoot){if(root==null)returnnewBSTInfo(int.MaxValue,int.MinValue,0);BSTInfoleft=LargestBstBt(root.left);BSTInforight=LargestBstBt(root.right);// Check if the current subtree is a BSTif(left.max<root.data&&right.min>root.data){returnnewBSTInfo(Math.Min(left.min,root.data),Math.Max(right.max,root.data),1+left.mxSz+right.mxSz);}returnnewBSTInfo(int.MinValue,int.MaxValue,Math.Max(left.mxSz,right.mxSz));}// Function to return the size of the largest BSTstaticintLargestBst(Noderoot){returnLargestBstBt(root).mxSz;}staticvoidMain(string[]args){// Constructed binary tree looks like this:// 60// / \// 65 70// /// 50Noderoot=newNode(60);root.left=newNode(65);root.right=newNode(70);root.left.left=newNode(50);Console.WriteLine(LargestBst(root));}}
JavaScript
// JavaScript Program to find Size of Largest// BST in a Binary TreeclassNode{constructor(data){this.data=data;this.left=null;this.right=null;}}// BSTInfo class to store subtree informationclassBSTInfo{constructor(min,max,maxSize){this.min=min;this.max=max;this.maxSize=maxSize;}}// Function to determine the largest BST// in the binary treefunctionlargestBSTBT(root){if(!root)returnnewBSTInfo(Number.MAX_SAFE_INTEGER,Number.MIN_SAFE_INTEGER,0);constleft=largestBSTBT(root.left);constright=largestBSTBT(root.right);// Check if the current subtree is a BSTif(left.max<root.data&&right.min>root.data){returnnewBSTInfo(Math.min(left.min,root.data),Math.max(right.max,root.data),1+left.maxSize+right.maxSize);}returnnewBSTInfo(Number.MIN_SAFE_INTEGER,Number.MAX_SAFE_INTEGER,Math.max(left.maxSize,right.maxSize));}// Function to return the size of the largest BSTfunctionlargestBST(root){returnlargestBSTBT(root).maxSize;}// Constructed binary tree looks like this:// 60// / \// 65 70// /// 50constroot=newNode(60);root.left=newNode(65);root.right=newNode(70);root.left.left=newNode(50);console.log(largestBST(root));